Merge changes Ib40df2a9,If24b8510,Ic8102680 into androidx-main

* changes:
  Add demos for DrawStyle in Text
  Introduce DrawStyle in TextStyle and SpanStyle to enable outlined text drawing.
  Add an Experimental DrawStyle parameter to `paint` methods in MultiParagraph.
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/StrokeDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/StrokeDemo.kt
new file mode 100644
index 0000000..c3c5211
--- /dev/null
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/StrokeDemo.kt
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.demos.text
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.material.LocalTextStyle
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.RadioButton
+import androidx.compose.material.Slider
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.PathEffect
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.graphics.StrokeJoin
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.text.ExperimentalTextApi
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+
+@OptIn(ExperimentalTextApi::class)
+@Composable
+fun TextStrokeDemo() {
+    var dashInterval by remember { mutableStateOf(2f) }
+    var stroke by remember {
+        mutableStateOf(
+            Stroke(
+                width = 4f, pathEffect = PathEffect.dashPathEffect(
+                    floatArrayOf(2f, 2f)
+                )
+            )
+        )
+    }
+    var fontSize by remember { mutableStateOf(20.sp) }
+
+    val finalStroke by remember {
+        derivedStateOf {
+            stroke.copy(
+                pathEffect = PathEffect.dashPathEffect(
+                    floatArrayOf(
+                        dashInterval,
+                        dashInterval
+                    ), phase = 0f
+                )
+            )
+        }
+    }
+    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
+        Text("Font Size")
+        Slider(
+            value = fontSize.value,
+            onValueChange = {
+                fontSize = it.sp
+            },
+            valueRange = 8f..144f
+        )
+        Text("Width")
+        Slider(
+            value = stroke.width,
+            onValueChange = {
+                stroke = stroke.copy(width = it)
+            },
+            valueRange = 0f..16f,
+            steps = 16
+        )
+        Text("Miter")
+        Slider(
+            value = stroke.miter,
+            onValueChange = {
+                stroke = stroke.copy(miter = it)
+            },
+            valueRange = 0f..16f,
+            steps = 16
+        )
+
+        Text("Dash on/off intervals")
+        Slider(
+            value = dashInterval,
+            onValueChange = { dashInterval = it },
+            valueRange = 0f..16f,
+            steps = 16
+        )
+
+        Text("Cap")
+        Row(
+            verticalAlignment = Alignment.CenterVertically,
+            horizontalArrangement = Arrangement.SpaceBetween
+        ) {
+            RadioButton(
+                selected = stroke.cap == StrokeCap.Butt,
+                onClick = { stroke = stroke.copy(cap = StrokeCap.Butt) })
+            Text(text = "Butt", style = MaterialTheme.typography.body2)
+
+            RadioButton(
+                selected = stroke.cap == StrokeCap.Round,
+                onClick = { stroke = stroke.copy(cap = StrokeCap.Round) })
+            Text(text = "Round", style = MaterialTheme.typography.body2)
+
+            RadioButton(
+                selected = stroke.cap == StrokeCap.Square,
+                onClick = { stroke = stroke.copy(cap = StrokeCap.Square) })
+            Text(text = "Square", style = MaterialTheme.typography.body2)
+        }
+
+        Text("Join")
+        Row(
+            verticalAlignment = Alignment.CenterVertically,
+            horizontalArrangement = Arrangement.SpaceBetween
+        ) {
+            RadioButton(
+                selected = stroke.join == StrokeJoin.Round,
+                onClick = { stroke = stroke.copy(join = StrokeJoin.Round) })
+            Text(text = "Round", style = MaterialTheme.typography.body2)
+
+            RadioButton(
+                selected = stroke.join == StrokeJoin.Miter,
+                onClick = { stroke = stroke.copy(join = StrokeJoin.Miter) })
+            Text(text = "Miter", style = MaterialTheme.typography.body2)
+
+            RadioButton(
+                selected = stroke.join == StrokeJoin.Bevel,
+                onClick = { stroke = stroke.copy(join = StrokeJoin.Bevel) })
+            Text(text = "Bevel", style = MaterialTheme.typography.body2)
+        }
+
+        Text(
+            text = "This text is drawn using stroke! 🎉",
+            style = LocalTextStyle.current.merge(
+                TextStyle(
+                    fontSize = fontSize,
+                    brush = Brush.horizontalGradient(
+                        listOf(
+                            Color.Red,
+                            Color.Green,
+                            Color.Blue
+                        )
+                    ), drawStyle = finalStroke
+                )
+            )
+        )
+    }
+}
+
+fun Stroke.copy(
+    width: Float = this.width,
+    miter: Float = this.miter,
+    cap: StrokeCap = this.cap,
+    join: StrokeJoin = this.join,
+    pathEffect: PathEffect? = this.pathEffect
+): Stroke {
+    return Stroke(width, miter, cap, join, pathEffect)
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextDemos.kt
index d1889d6..e539ce9 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextDemos.kt
@@ -24,8 +24,14 @@
     listOf(
         ComposableDemo("Hyphens") { TextDemoHyphens() },
         ComposableDemo("Static text") { TextDemo() },
-        ComposableDemo("Canvas") { DrawTextDemo() },
-        ComposableDemo("Brush") { TextBrushDemo() },
+        DemoCategory(
+            "Text Canvas",
+            listOf(
+                ComposableDemo("Brush") { TextBrushDemo() },
+                ComposableDemo("drawText") { DrawTextDemo() },
+                ComposableDemo("Stroke") { TextStrokeDemo() }
+            )
+        ),
         ComposableDemo("Ellipsize") { EllipsizeDemo() },
         ComposableDemo("Typeface") { TypefaceDemo() },
         ComposableDemo("Variable Fonts") { VariableFontsDemo() },
diff --git a/compose/ui/ui-text/api/public_plus_experimental_current.txt b/compose/ui/ui-text/api/public_plus_experimental_current.txt
index b476a46..5a59852 100644
--- a/compose/ui/ui-text/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-text/api/public_plus_experimental_current.txt
@@ -142,7 +142,8 @@
     method public long getWordBoundary(int offset);
     method public boolean isLineEllipsized(int lineIndex);
     method public void paint(androidx.compose.ui.graphics.Canvas canvas, optional long color, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? decoration);
-    method @androidx.compose.ui.text.ExperimentalTextApi public void paint(androidx.compose.ui.graphics.Canvas canvas, androidx.compose.ui.graphics.Brush brush, optional float alpha, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? decoration);
+    method @androidx.compose.ui.text.ExperimentalTextApi public void paint(androidx.compose.ui.graphics.Canvas canvas, optional long color, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? decoration, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
+    method @androidx.compose.ui.text.ExperimentalTextApi public void paint(androidx.compose.ui.graphics.Canvas canvas, androidx.compose.ui.graphics.Brush brush, optional float alpha, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? decoration, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
     property public final boolean didExceedMaxLines;
     property public final float firstBaseline;
     property public final float height;
@@ -343,15 +344,18 @@
   @androidx.compose.runtime.Immutable public final class SpanStyle {
     ctor public SpanStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
     ctor public SpanStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
-    ctor @androidx.compose.ui.text.ExperimentalTextApi public SpanStyle(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
+    ctor @androidx.compose.ui.text.ExperimentalTextApi public SpanStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
+    ctor @androidx.compose.ui.text.ExperimentalTextApi public SpanStyle(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
     method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
     method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
-    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.SpanStyle copy(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
+    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
+    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.SpanStyle copy(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
     method @androidx.compose.ui.text.ExperimentalTextApi public float getAlpha();
     method public long getBackground();
     method public androidx.compose.ui.text.style.BaselineShift? getBaselineShift();
     method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.graphics.Brush? getBrush();
     method public long getColor();
+    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.graphics.drawscope.DrawStyle? getDrawStyle();
     method public androidx.compose.ui.text.font.FontFamily? getFontFamily();
     method public String? getFontFeatureSettings();
     method public long getFontSize();
@@ -371,6 +375,7 @@
     property public final androidx.compose.ui.text.style.BaselineShift? baselineShift;
     property @androidx.compose.ui.text.ExperimentalTextApi public final androidx.compose.ui.graphics.Brush? brush;
     property public final long color;
+    property @androidx.compose.ui.text.ExperimentalTextApi public final androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle;
     property public final androidx.compose.ui.text.font.FontFamily? fontFamily;
     property public final String? fontFeatureSettings;
     property public final long fontSize;
@@ -528,17 +533,18 @@
   @androidx.compose.runtime.Immutable public final class TextStyle {
     ctor public TextStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
     ctor public TextStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
-    ctor @androidx.compose.ui.text.ExperimentalTextApi public TextStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
-    ctor @androidx.compose.ui.text.ExperimentalTextApi public TextStyle(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
+    ctor @androidx.compose.ui.text.ExperimentalTextApi public TextStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
+    ctor @androidx.compose.ui.text.ExperimentalTextApi public TextStyle(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
     method public androidx.compose.ui.text.TextStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
     method public androidx.compose.ui.text.TextStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
-    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.TextStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
-    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.TextStyle copy(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
+    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.TextStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
+    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.TextStyle copy(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
     method @androidx.compose.ui.text.ExperimentalTextApi public float getAlpha();
     method public long getBackground();
     method public androidx.compose.ui.text.style.BaselineShift? getBaselineShift();
     method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.graphics.Brush? getBrush();
     method public long getColor();
+    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.graphics.drawscope.DrawStyle? getDrawStyle();
     method public androidx.compose.ui.text.font.FontFamily? getFontFamily();
     method public String? getFontFeatureSettings();
     method public long getFontSize();
@@ -572,6 +578,7 @@
     property public final androidx.compose.ui.text.style.BaselineShift? baselineShift;
     property @androidx.compose.ui.text.ExperimentalTextApi public final androidx.compose.ui.graphics.Brush? brush;
     property public final long color;
+    property @androidx.compose.ui.text.ExperimentalTextApi public final androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle;
     property public final androidx.compose.ui.text.font.FontFamily? fontFamily;
     property public final String? fontFeatureSettings;
     property public final long fontSize;
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt
index f7af201..9bc2c68 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt
@@ -36,6 +36,7 @@
 import androidx.compose.ui.graphics.SolidColor
 import androidx.compose.ui.graphics.StrokeCap
 import androidx.compose.ui.graphics.StrokeJoin
+import androidx.compose.ui.graphics.drawscope.Fill
 import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.text.FontTestData.Companion.BASIC_MEASURE_FONT
@@ -57,6 +58,7 @@
 import androidx.compose.ui.text.intl.LocaleList
 import androidx.compose.ui.text.matchers.assertThat
 import androidx.compose.ui.text.platform.bitmap
+import androidx.compose.ui.text.platform.style.DrawStyleSpan
 import androidx.compose.ui.text.platform.style.ShaderBrushSpan
 import androidx.compose.ui.text.style.BaselineShift
 import androidx.compose.ui.text.style.TextAlign
@@ -905,6 +907,80 @@
             }
     }
 
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun testAnnotatedString_setDrawStyle() {
+        val text = "abcde"
+        val strokeWidth = 8f
+        val strokeMiter = 4f
+        val strokeCap = StrokeCap.Round
+        val strokeJoin = StrokeJoin.Bevel
+        val spanStyle = SpanStyle(drawStyle = Stroke(
+            strokeWidth,
+            strokeMiter,
+            strokeCap,
+            strokeJoin
+        ))
+
+        val paragraph = simpleParagraph(
+            text = text,
+            spanStyles = listOf(
+                AnnotatedString.Range(spanStyle, start = 0, end = text.length)
+            ),
+            width = 0.0f
+        )
+
+        assertThat(paragraph.charSequence)
+            .hasSpan(DrawStyleSpan::class, start = 0, end = text.length) {
+                return@hasSpan it.drawStyle == Stroke(
+                    strokeWidth,
+                    strokeMiter,
+                    strokeCap,
+                    strokeJoin
+                )
+            }
+    }
+
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun testAnnotatedString_setDrawStyle_FillOnTopOfStroke() {
+        val text = "abcde"
+        val strokeWidth = 8f
+        val strokeMiter = 4f
+        val strokeCap = StrokeCap.Round
+        val strokeJoin = StrokeJoin.Bevel
+        val strokeSpanStyle = SpanStyle(drawStyle = Stroke(
+            strokeWidth,
+            strokeMiter,
+            strokeCap,
+            strokeJoin
+        ))
+        val fillSpanStyle = SpanStyle(drawStyle = Fill)
+
+        val paragraph = simpleParagraph(
+            text = text,
+            spanStyles = listOf(
+                AnnotatedString.Range(strokeSpanStyle, start = 0, end = text.length),
+                AnnotatedString.Range(fillSpanStyle, start = 1, end = 3)
+            ),
+            width = 0.0f
+        )
+
+        assertThat(paragraph.charSequence)
+            .hasSpan(DrawStyleSpan::class, start = 0, end = text.length) {
+                return@hasSpan it.drawStyle == Stroke(
+                    strokeWidth,
+                    strokeMiter,
+                    strokeCap,
+                    strokeJoin
+                )
+            }
+        assertThat(paragraph.charSequence)
+            .hasSpanOnTop(DrawStyleSpan::class, start = 1, end = 3) {
+                return@hasSpanOnTop it.drawStyle == Fill
+            }
+    }
+
     @Test
     fun testAnnotatedString_fontFeatureSetting_setSpanOnText() {
         val text = "abc"
@@ -1386,6 +1462,39 @@
             .hasSpan(TextDecorationSpan::class, 0, text.length) { it.isStrikethroughText }
     }
 
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun testSpanStyle_drawStyle_stroke_appliedOnTextPaint() {
+        val paragraph = simpleParagraph(
+            text = "",
+            style = TextStyle(drawStyle = Stroke(
+                width = 8f,
+                miter = 6f,
+                cap = StrokeCap.Round,
+                join = StrokeJoin.Bevel
+            )),
+            width = 0.0f
+        )
+
+        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.STROKE)
+        assertThat(paragraph.textPaint.strokeWidth).isEqualTo(8f)
+        assertThat(paragraph.textPaint.strokeMiter).isEqualTo(6f)
+        assertThat(paragraph.textPaint.strokeCap).isEqualTo(Paint.Cap.ROUND)
+        assertThat(paragraph.textPaint.strokeJoin).isEqualTo(Paint.Join.BEVEL)
+    }
+
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun testSpanStyle_drawStyle_fill_appliedOnTextPaint() {
+        val paragraph = simpleParagraph(
+            text = "",
+            style = TextStyle(drawStyle = Fill),
+            width = 0.0f
+        )
+
+        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.FILL)
+    }
+
     @Test
     fun testSpanStyle_background_appliedAsSpan() {
         // bgColor is reset in the Android Layout constructor.
@@ -1455,6 +1564,60 @@
         assertThat(paragraph.textPaint.isUnderlineText).isTrue()
     }
 
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun testPaint_can_change_DrawStyle_to_Stroke() {
+        val paragraph = simpleParagraph(
+            text = "",
+            style = TextStyle(drawStyle = null),
+            width = 0.0f
+        )
+        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.FILL)
+
+        val stroke = Stroke(width = 4f, miter = 2f, cap = StrokeCap.Square, join = StrokeJoin.Bevel)
+        val canvas = Canvas(android.graphics.Canvas())
+        paragraph.paint(canvas, drawStyle = stroke)
+
+        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.STROKE)
+        assertThat(paragraph.textPaint.strokeWidth).isEqualTo(4f)
+        assertThat(paragraph.textPaint.strokeMiter).isEqualTo(2f)
+        assertThat(paragraph.textPaint.strokeCap).isEqualTo(Paint.Cap.SQUARE)
+        assertThat(paragraph.textPaint.strokeJoin).isEqualTo(Paint.Join.BEVEL)
+    }
+
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun testPaint_can_change_DrawStyle_to_Fill() {
+        val paragraph = simpleParagraph(
+            text = "",
+            style = TextStyle(drawStyle = Stroke(8f)),
+            width = 0.0f
+        )
+        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.STROKE)
+        assertThat(paragraph.textPaint.strokeWidth).isEqualTo(8f)
+
+        val canvas = Canvas(android.graphics.Canvas())
+        paragraph.paint(canvas, drawStyle = Fill)
+        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.FILL)
+    }
+
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun testPaint_null_drawStyle_should_be_noop() {
+        val paragraph = simpleParagraph(
+            text = "",
+            style = TextStyle(drawStyle = Stroke(8f)),
+            width = 0.0f
+        )
+        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.STROKE)
+        assertThat(paragraph.textPaint.strokeWidth).isEqualTo(8f)
+
+        val canvas = Canvas(android.graphics.Canvas())
+        paragraph.paint(canvas, drawStyle = null)
+        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.STROKE)
+        assertThat(paragraph.textPaint.strokeWidth).isEqualTo(8f)
+    }
+
     @SdkSuppress(minSdkVersion = 29)
     @Test
     fun testPaint_can_change_Shadow() {
@@ -1664,24 +1827,6 @@
     }
 
     @Test
-    fun testPaint_can_change_drawStyle_to_Stroke() {
-        val paragraph = simpleParagraph(
-            text = "",
-            width = 0.0f
-        )
-        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.FILL)
-
-        val stroke = Stroke(width = 4f, miter = 2f, cap = StrokeCap.Square, join = StrokeJoin.Bevel)
-        val canvas = Canvas(android.graphics.Canvas())
-        paragraph.paint(canvas, drawStyle = stroke)
-        assertThat(paragraph.textPaint.style).isEqualTo(Paint.Style.STROKE)
-        assertThat(paragraph.textPaint.strokeWidth).isEqualTo(4f)
-        assertThat(paragraph.textPaint.strokeMiter).isEqualTo(2f)
-        assertThat(paragraph.textPaint.strokeCap).isEqualTo(Paint.Cap.SQUARE)
-        assertThat(paragraph.textPaint.strokeJoin).isEqualTo(Paint.Join.BEVEL)
-    }
-
-    @Test
     fun testSpanStyle_baselineShift_appliedAsSpan() {
         // baselineShift is reset in the Android Layout constructor.
         // therefore we cannot apply them on paint, have to use spans.
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
index 79d2d1c..c2d97d7 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
@@ -15,12 +15,14 @@
  */
 package androidx.compose.ui.text
 
+import android.graphics.Paint
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Path
 import androidx.compose.ui.graphics.PathOperation
+import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.text.AnnotatedString.Range
 import androidx.compose.ui.text.FontTestData.Companion.BASIC_MEASURE_FONT
 import androidx.compose.ui.text.font.toFontFamily
@@ -1582,6 +1584,31 @@
             .isEqualToBitmap(multiParagraph2.bitmap(brush, 0.5f))
     }
 
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun multiParagraph_appliesDrawStyle_toAllParagraphs() = with(defaultDensity) {
+        val fontSize = 20.sp
+        val fontSizeInPx = fontSize.toPx()
+        val multiParagraph = simpleMultiParagraph(
+            text = buildAnnotatedString {
+                withStyle(ParagraphStyle(textAlign = TextAlign.Right)) {
+                    append("Lorem")
+                }
+                withStyle(ParagraphStyle()) {
+                    append("Ipsum")
+                }
+            },
+            style = TextStyle(fontSize = fontSize),
+            width = fontSizeInPx * 5
+        )
+
+        multiParagraph.bitmap(drawStyle = Stroke())
+
+        multiParagraph.paragraphInfoList.map { it.paragraph }.forEach {
+            assertThat((it as AndroidParagraph).textPaint.style).isEqualTo(Paint.Style.STROKE)
+        }
+    }
+
     private fun MultiParagraph.disableAntialias() {
         paragraphInfoList.forEach {
             (it.paragraph as AndroidParagraph).textPaint.isAntiAlias = false
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/TextTestExtensions.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/TextTestExtensions.kt
index a476fc4..80922f2 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/TextTestExtensions.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/TextTestExtensions.kt
@@ -94,7 +94,9 @@
 @OptIn(ExperimentalTextApi::class)
 fun MultiParagraph.bitmap(
     brush: Brush? = null,
-    alpha: Float = Float.NaN
+    alpha: Float = Float.NaN,
+    textDecoration: TextDecoration? = null,
+    drawStyle: DrawStyle? = null
 ): Bitmap {
     val width = paragraphInfoList.maxByOrNull { it.paragraph.width }?.paragraph?.width ?: 0f
     val bitmap = Bitmap.createBitmap(
@@ -104,13 +106,17 @@
     )
     if (brush != null) {
         this.paint(
-            canvas = androidx.compose.ui.graphics.Canvas(Canvas(bitmap)),
-            brush = brush,
-            alpha = alpha
+            androidx.compose.ui.graphics.Canvas(Canvas(bitmap)),
+            brush,
+            alpha,
+            decoration = textDecoration,
+            drawStyle = drawStyle
         )
     } else {
         this.paint(
-            canvas = androidx.compose.ui.graphics.Canvas(Canvas(bitmap))
+            canvas = androidx.compose.ui.graphics.Canvas(Canvas(bitmap)),
+            decoration = textDecoration,
+            drawStyle = drawStyle
         )
     }
     return bitmap
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidMultiParagraphDraw.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidMultiParagraphDraw.kt
index 8d7dead..80fb14c 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidMultiParagraphDraw.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidMultiParagraphDraw.kt
@@ -23,6 +23,7 @@
 import androidx.compose.ui.graphics.ShaderBrush
 import androidx.compose.ui.graphics.Shadow
 import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.drawscope.DrawStyle
 import androidx.compose.ui.text.ExperimentalTextApi
 import androidx.compose.ui.text.MultiParagraph
 import androidx.compose.ui.text.style.TextDecoration
@@ -34,15 +35,16 @@
     brush: Brush,
     alpha: Float,
     shadow: Shadow?,
-    decoration: TextDecoration?
+    decoration: TextDecoration?,
+    drawStyle: DrawStyle?
 ) {
     canvas.save()
 
     if (paragraphInfoList.size <= 1) {
-        drawParagraphs(canvas, brush, alpha, shadow, decoration)
+        drawParagraphs(canvas, brush, alpha, shadow, decoration, drawStyle)
     } else {
         when (brush) {
-            is SolidColor -> drawParagraphs(canvas, brush, alpha, shadow, decoration)
+            is SolidColor -> drawParagraphs(canvas, brush, alpha, shadow, decoration, drawStyle)
             is ShaderBrush -> {
                 var height = 0f
                 var width = 0f
@@ -54,7 +56,14 @@
                 val matrix = Matrix()
                 shader.getLocalMatrix(matrix)
                 paragraphInfoList.fastForEach {
-                    it.paragraph.paint(canvas, ShaderBrush(shader), alpha, shadow, decoration)
+                    it.paragraph.paint(
+                        canvas = canvas,
+                        brush = ShaderBrush(shader),
+                        alpha = alpha,
+                        shadow = shadow,
+                        textDecoration = decoration,
+                        drawStyle = drawStyle
+                    )
                     canvas.translate(0f, it.paragraph.height)
                     matrix.setTranslate(0f, -it.paragraph.height)
                     shader.setLocalMatrix(matrix)
@@ -72,10 +81,11 @@
     brush: Brush,
     alpha: Float,
     shadow: Shadow?,
-    decoration: TextDecoration?
+    decoration: TextDecoration?,
+    drawStyle: DrawStyle?
 ) {
     paragraphInfoList.fastForEach {
-        it.paragraph.paint(canvas, brush, alpha, shadow, decoration)
+        it.paragraph.paint(canvas, brush, alpha, shadow, decoration, drawStyle)
         canvas.translate(0f, it.paragraph.height)
     }
 }
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt
index ebb94c0..3b6a1cc 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt
@@ -139,7 +139,7 @@
     }
 }
 
-private fun StrokeJoin.toAndroidJoin(): Paint.Join {
+internal fun StrokeJoin.toAndroidJoin(): Paint.Join {
     return when (this) {
         StrokeJoin.Miter -> Paint.Join.MITER
         StrokeJoin.Round -> Paint.Join.ROUND
@@ -148,7 +148,7 @@
     }
 }
 
-private fun StrokeCap.toAndroidCap(): Paint.Cap {
+internal fun StrokeCap.toAndroidCap(): Paint.Cap {
     return when (this) {
         StrokeCap.Butt -> Paint.Cap.BUTT
         StrokeCap.Round -> Paint.Cap.ROUND
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt
index bc744a8..20dbff0 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt
@@ -33,6 +33,7 @@
 import androidx.compose.ui.graphics.ShaderBrush
 import androidx.compose.ui.graphics.Shadow
 import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.drawscope.DrawStyle
 import androidx.compose.ui.graphics.isSpecified
 import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.text.AnnotatedString
@@ -59,6 +60,7 @@
 import androidx.compose.ui.text.intersect
 import androidx.compose.ui.text.intl.Locale
 import androidx.compose.ui.text.intl.LocaleList
+import androidx.compose.ui.text.platform.style.DrawStyleSpan
 import androidx.compose.ui.text.platform.style.ShaderBrushSpan
 import androidx.compose.ui.text.style.BaselineShift
 import androidx.compose.ui.text.style.LineHeightStyle
@@ -237,6 +239,8 @@
 
     setShadow(style.shadow, start, end)
 
+    setDrawStyle(style.drawStyle, start, end)
+
     createLetterSpacingSpan(style.letterSpacing, density)?.let {
         lowPrioritySpans.add(
             SpanRange(it, start, end)
@@ -415,6 +419,13 @@
     }
 }
 
+@OptIn(InternalPlatformTextApi::class)
+private fun Spannable.setDrawStyle(drawStyle: DrawStyle?, start: Int, end: Int) {
+    drawStyle?.let {
+        setSpan(DrawStyleSpan(it), start, end)
+    }
+}
+
 internal fun Spannable.setBackground(color: Color, start: Int, end: Int) {
     if (color.isSpecified) {
         setSpan(
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt
index 12141cd..4a57356 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt
@@ -107,6 +107,7 @@
     setBrush(style.brush, Size.Unspecified, style.alpha)
     setShadow(style.shadow)
     // Skip textDecoration (b/199939617). TextDecoration should be applied as a span.
+    setDrawStyle(style.drawStyle)
 
     // letterSpacing with unit Sp needs to be handled by span.
     // baselineShift and bgColor is reset in the Android Layout constructor,
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/style/DrawStyleSpan.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/style/DrawStyleSpan.android.kt
new file mode 100644
index 0000000..6b0a86c
--- /dev/null
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/style/DrawStyleSpan.android.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.text.platform.style
+
+import android.graphics.Paint
+import android.text.TextPaint
+import android.text.style.CharacterStyle
+import android.text.style.UpdateAppearance
+import androidx.compose.ui.graphics.ShaderBrush
+import androidx.compose.ui.graphics.asAndroidPathEffect
+import androidx.compose.ui.graphics.drawscope.DrawStyle
+import androidx.compose.ui.graphics.drawscope.Fill
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.text.platform.toAndroidCap
+import androidx.compose.ui.text.platform.toAndroidJoin
+
+/**
+ * A span that applies [ShaderBrush] to TextPaint after receiving a specified size
+ */
+internal class DrawStyleSpan(
+    val drawStyle: DrawStyle
+) : CharacterStyle(), UpdateAppearance {
+    override fun updateDrawState(textPaint: TextPaint?) {
+        textPaint?.run {
+            when (drawStyle) {
+                Fill -> style = Paint.Style.FILL
+                is Stroke -> {
+                    style = Paint.Style.STROKE
+                    strokeWidth = drawStyle.width
+                    strokeMiter = drawStyle.miter
+                    strokeJoin = drawStyle.join.toAndroidJoin()
+                    strokeCap = drawStyle.cap.toAndroidCap()
+                    pathEffect = drawStyle.pathEffect?.asAndroidPathEffect()
+                }
+            }
+        }
+    }
+}
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt
index 3780431..b3cd8cd 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt
@@ -23,6 +23,7 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Path
 import androidx.compose.ui.graphics.Shadow
+import androidx.compose.ui.graphics.drawscope.DrawStyle
 import androidx.compose.ui.text.font.Font
 import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.font.createFontFamilyResolver
@@ -402,12 +403,30 @@
     @ExperimentalTextApi
     fun paint(
         canvas: Canvas,
+        color: Color = Color.Unspecified,
+        shadow: Shadow? = null,
+        decoration: TextDecoration? = null,
+        drawStyle: DrawStyle? = null
+    ) {
+        canvas.save()
+        paragraphInfoList.fastForEach {
+            it.paragraph.paint(canvas, color, shadow, decoration, drawStyle)
+            canvas.translate(0f, it.paragraph.height)
+        }
+        canvas.restore()
+    }
+
+    /** Paint the paragraphs to canvas. */
+    @ExperimentalTextApi
+    fun paint(
+        canvas: Canvas,
         brush: Brush,
         alpha: Float = Float.NaN,
         shadow: Shadow? = null,
-        decoration: TextDecoration? = null
+        decoration: TextDecoration? = null,
+        drawStyle: DrawStyle? = null
     ) {
-        drawMultiParagraph(canvas, brush, alpha, shadow, decoration)
+        drawMultiParagraph(canvas, brush, alpha, shadow, decoration, drawStyle)
     }
 
     /** Returns path that enclose the given text range. */
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt
index a9c1504..aafe77a 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt
@@ -21,6 +21,8 @@
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shadow
+import androidx.compose.ui.graphics.drawscope.DrawStyle
+import androidx.compose.ui.graphics.drawscope.Fill
 import androidx.compose.ui.graphics.lerp
 import androidx.compose.ui.graphics.takeOrElse
 import androidx.compose.ui.text.font.FontFamily
@@ -74,6 +76,8 @@
  * @param textDecoration The decorations to paint on the text (e.g., an underline).
  * @param shadow The shadow effect applied on the text.
  * @param platformStyle Platform specific [SpanStyle] parameters.
+ * @param drawStyle Drawing style of text, whether fill in the text while drawing or stroke around
+ * the edges.
  *
  * @see AnnotatedString
  * @see TextStyle
@@ -96,7 +100,10 @@
     val background: Color = Color.Unspecified,
     val textDecoration: TextDecoration? = null,
     val shadow: Shadow? = null,
-    val platformStyle: PlatformSpanStyle? = null
+    val platformStyle: PlatformSpanStyle? = null,
+    @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
+    @property:ExperimentalTextApi
+    @get:ExperimentalTextApi val drawStyle: DrawStyle? = null
 ) {
 
     /**
@@ -236,6 +243,78 @@
      * in order to set paragraph level styling such as line height, or text alignment please see
      * [ParagraphStyle].
      *
+     * @sample androidx.compose.ui.text.samples.SpanStyleSample
+     *
+     * @sample androidx.compose.ui.text.samples.AnnotatedStringBuilderSample
+     *
+     * @param color The color to draw the text.
+     * @param fontSize The size of glyphs (in logical pixels) to use when painting the text. This
+     * may be [TextUnit.Unspecified] for inheriting from another [SpanStyle].
+     * @param fontWeight The typeface thickness to use when painting the text (e.g., bold).
+     * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic).
+     * @param fontSynthesis Whether to synthesize font weight and/or style when the requested weight
+     * or style cannot be found in the provided font family.
+     * @param fontFamily The font family to be used when rendering the text.
+     * @param fontFeatureSettings The advanced typography settings provided by font. The format is
+     * the same as the CSS font-feature-settings attribute:
+     *  https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop
+     * @param letterSpacing The amount of space (in em) to add between each letter.
+     * @param baselineShift The amount by which the text is shifted up from the current baseline.
+     * @param textGeometricTransform The geometric transformation applied the text.
+     * @param localeList The locale list used to select region-specific glyphs.
+     * @param background The background color for the text.
+     * @param textDecoration The decorations to paint on the text (e.g., an underline).
+     * @param shadow The shadow effect applied on the text.
+     * @param platformStyle Platform specific [SpanStyle] parameters.
+     * @param drawStyle Drawing style of text, whether fill in the text while drawing or stroke
+     * around the edges.
+     *
+     * @see AnnotatedString
+     * @see TextStyle
+     * @see ParagraphStyle
+     */
+    @ExperimentalTextApi
+    constructor(
+        color: Color = Color.Unspecified,
+        fontSize: TextUnit = TextUnit.Unspecified,
+        fontWeight: FontWeight? = null,
+        fontStyle: FontStyle? = null,
+        fontSynthesis: FontSynthesis? = null,
+        fontFamily: FontFamily? = null,
+        fontFeatureSettings: String? = null,
+        letterSpacing: TextUnit = TextUnit.Unspecified,
+        baselineShift: BaselineShift? = null,
+        textGeometricTransform: TextGeometricTransform? = null,
+        localeList: LocaleList? = null,
+        background: Color = Color.Unspecified,
+        textDecoration: TextDecoration? = null,
+        shadow: Shadow? = null,
+        platformStyle: PlatformSpanStyle? = null,
+        drawStyle: DrawStyle? = null
+    ) : this(
+        textForegroundStyle = TextForegroundStyle.from(color),
+        fontSize = fontSize,
+        fontWeight = fontWeight,
+        fontStyle = fontStyle,
+        fontSynthesis = fontSynthesis,
+        fontFamily = fontFamily,
+        fontFeatureSettings = fontFeatureSettings,
+        letterSpacing = letterSpacing,
+        baselineShift = baselineShift,
+        textGeometricTransform = textGeometricTransform,
+        localeList = localeList,
+        background = background,
+        textDecoration = textDecoration,
+        shadow = shadow,
+        platformStyle = platformStyle,
+        drawStyle = drawStyle
+    )
+
+    /**
+     * Styling configuration for a text span. This configuration only allows character level styling,
+     * in order to set paragraph level styling such as line height, or text alignment please see
+     * [ParagraphStyle].
+     *
      * @sample androidx.compose.ui.text.samples.SpanStyleBrushSample
      *
      * @sample androidx.compose.ui.text.samples.AnnotatedStringBuilderSample
@@ -263,6 +342,8 @@
      * @param textDecoration The decorations to paint on the text (e.g., an underline).
      * @param shadow The shadow effect applied on the text.
      * @param platformStyle Platform specific [SpanStyle] parameters.
+     * @param drawStyle Drawing style of text, whether fill in the text while drawing or stroke
+     * around the edges.
      *
      * @see AnnotatedString
      * @see TextStyle
@@ -285,7 +366,8 @@
         background: Color = Color.Unspecified,
         textDecoration: TextDecoration? = null,
         shadow: Shadow? = null,
-        platformStyle: PlatformSpanStyle? = null
+        platformStyle: PlatformSpanStyle? = null,
+        drawStyle: DrawStyle? = null
     ) : this(
         textForegroundStyle = TextForegroundStyle.from(brush, alpha),
         fontSize = fontSize,
@@ -301,7 +383,8 @@
         background = background,
         textDecoration = textDecoration,
         shadow = shadow,
-        platformStyle = platformStyle
+        platformStyle = platformStyle,
+        drawStyle = drawStyle
     )
 
     /**
@@ -335,6 +418,7 @@
      *
      * If the given span style is null, returns this span style.
      */
+    @OptIn(ExperimentalTextApi::class)
     @Stable
     fun merge(other: SpanStyle? = null): SpanStyle {
         if (other == null) return this
@@ -358,7 +442,8 @@
             background = other.background.takeOrElse { this.background },
             textDecoration = other.textDecoration ?: this.textDecoration,
             shadow = other.shadow ?: this.shadow,
-            platformStyle = mergePlatformStyle(other.platformStyle)
+            platformStyle = mergePlatformStyle(other.platformStyle),
+            drawStyle = other.drawStyle ?: this.drawStyle
         )
     }
 
@@ -374,6 +459,7 @@
     @Stable
     operator fun plus(other: SpanStyle): SpanStyle = this.merge(other)
 
+    @OptIn(ExperimentalTextApi::class)
     fun copy(
         color: Color = this.color,
         fontSize: TextUnit = this.fontSize,
@@ -409,7 +495,8 @@
             background = background,
             textDecoration = textDecoration,
             shadow = shadow,
-            platformStyle = this.platformStyle
+            platformStyle = this.platformStyle,
+            drawStyle = this.drawStyle
         )
     }
 
@@ -455,6 +542,49 @@
 
     @ExperimentalTextApi
     fun copy(
+        color: Color = this.color,
+        fontSize: TextUnit = this.fontSize,
+        fontWeight: FontWeight? = this.fontWeight,
+        fontStyle: FontStyle? = this.fontStyle,
+        fontSynthesis: FontSynthesis? = this.fontSynthesis,
+        fontFamily: FontFamily? = this.fontFamily,
+        fontFeatureSettings: String? = this.fontFeatureSettings,
+        letterSpacing: TextUnit = this.letterSpacing,
+        baselineShift: BaselineShift? = this.baselineShift,
+        textGeometricTransform: TextGeometricTransform? = this.textGeometricTransform,
+        localeList: LocaleList? = this.localeList,
+        background: Color = this.background,
+        textDecoration: TextDecoration? = this.textDecoration,
+        shadow: Shadow? = this.shadow,
+        platformStyle: PlatformSpanStyle? = this.platformStyle,
+        drawStyle: DrawStyle? = this.drawStyle
+    ): SpanStyle {
+        return SpanStyle(
+            textForegroundStyle = if (color == this.color) {
+                textForegroundStyle
+            } else {
+                TextForegroundStyle.from(color)
+            },
+            fontSize = fontSize,
+            fontWeight = fontWeight,
+            fontStyle = fontStyle,
+            fontSynthesis = fontSynthesis,
+            fontFamily = fontFamily,
+            fontFeatureSettings = fontFeatureSettings,
+            letterSpacing = letterSpacing,
+            baselineShift = baselineShift,
+            textGeometricTransform = textGeometricTransform,
+            localeList = localeList,
+            background = background,
+            textDecoration = textDecoration,
+            shadow = shadow,
+            platformStyle = platformStyle,
+            drawStyle = drawStyle
+        )
+    }
+
+    @ExperimentalTextApi
+    fun copy(
         brush: Brush?,
         alpha: Float = this.alpha,
         fontSize: TextUnit = this.fontSize,
@@ -470,7 +600,8 @@
         background: Color = this.background,
         textDecoration: TextDecoration? = this.textDecoration,
         shadow: Shadow? = this.shadow,
-        platformStyle: PlatformSpanStyle? = this.platformStyle
+        platformStyle: PlatformSpanStyle? = this.platformStyle,
+        drawStyle: DrawStyle? = this.drawStyle
     ): SpanStyle {
         return SpanStyle(
             textForegroundStyle = TextForegroundStyle.from(brush, alpha),
@@ -487,7 +618,8 @@
             background = background,
             textDecoration = textDecoration,
             shadow = shadow,
-            platformStyle = platformStyle
+            platformStyle = platformStyle,
+            drawStyle = drawStyle
         )
     }
 
@@ -515,10 +647,12 @@
         return true
     }
 
+    @OptIn(ExperimentalTextApi::class)
     private fun hasSameNonLayoutAttributes(other: SpanStyle): Boolean {
         if (textForegroundStyle != other.textForegroundStyle) return false
         if (textDecoration != other.textDecoration) return false
         if (shadow != other.shadow) return false
+        if (drawStyle != other.drawStyle) return false
         return true
     }
 
@@ -541,6 +675,7 @@
         result = 31 * result + (textDecoration?.hashCode() ?: 0)
         result = 31 * result + (shadow?.hashCode() ?: 0)
         result = 31 * result + (platformStyle?.hashCode() ?: 0)
+        result = 31 * result + (drawStyle?.hashCode() ?: 0)
         return result
     }
 
@@ -579,7 +714,8 @@
             "background=$background, " +
             "textDecoration=$textDecoration, " +
             "shadow=$shadow, " +
-            "platformStyle=$platformStyle" +
+            "platformStyle=$platformStyle, " +
+            "drawStyle=$drawStyle" +
             ")"
     }
 }
@@ -612,6 +748,7 @@
  * between [start] and [stop]. The interpolation can be extrapolated beyond 0.0 and
  * 1.0, so negative values and values greater than 1.0 are valid.
  */
+@OptIn(ExperimentalTextApi::class)
 fun lerp(start: SpanStyle, stop: SpanStyle, fraction: Float): SpanStyle {
     return SpanStyle(
         textForegroundStyle = lerp(start.textForegroundStyle, stop.textForegroundStyle, fraction),
@@ -672,7 +809,12 @@
             stop.shadow ?: Shadow(),
             fraction
         ),
-        platformStyle = lerpPlatformStyle(start.platformStyle, stop.platformStyle, fraction)
+        platformStyle = lerpPlatformStyle(start.platformStyle, stop.platformStyle, fraction),
+        drawStyle = lerpDiscrete(
+            start.drawStyle,
+            stop.drawStyle,
+            fraction
+        )
     )
 }
 
@@ -687,6 +829,7 @@
     return lerp(startNonNull, stopNonNull, fraction)
 }
 
+@OptIn(ExperimentalTextApi::class)
 internal fun resolveSpanStyleDefaults(style: SpanStyle) = SpanStyle(
     textForegroundStyle = style.textForegroundStyle.takeOrElse {
         TextForegroundStyle.from(DefaultColor)
@@ -708,5 +851,6 @@
     background = style.background.takeOrElse { DefaultBackgroundColor },
     textDecoration = style.textDecoration ?: TextDecoration.None,
     shadow = style.shadow ?: Shadow.None,
-    platformStyle = style.platformStyle
+    platformStyle = style.platformStyle,
+    drawStyle = style.drawStyle ?: Fill
 )
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
index b2ba6b9..4f565ed 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
@@ -64,14 +64,16 @@
                     brush,
                     textLayoutResult.layoutInput.style.alpha,
                     textLayoutResult.layoutInput.style.shadow,
-                    textLayoutResult.layoutInput.style.textDecoration
+                    textLayoutResult.layoutInput.style.textDecoration,
+                    textLayoutResult.layoutInput.style.drawStyle
                 )
             } else {
                 textLayoutResult.multiParagraph.paint(
                     canvas,
                     textLayoutResult.layoutInput.style.color,
                     textLayoutResult.layoutInput.style.shadow,
-                    textLayoutResult.layoutInput.style.textDecoration
+                    textLayoutResult.layoutInput.style.textDecoration,
+                    textLayoutResult.layoutInput.style.drawStyle
                 )
             }
         } finally {
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextStyle.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextStyle.kt
index 00bf72c..de73bcb 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextStyle.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextStyle.kt
@@ -21,6 +21,7 @@
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shadow
+import androidx.compose.ui.graphics.drawscope.DrawStyle
 import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.font.FontStyle
 import androidx.compose.ui.text.font.FontSynthesis
@@ -261,6 +262,8 @@
      * @param background The background color for the text.
      * @param textDecoration The decorations to paint on the text (e.g., an underline).
      * @param shadow The shadow effect applied on the text.
+     * @param drawStyle Drawing style of text, whether fill in the text while drawing or stroke
+     * around the edges.
      * @param textAlign The alignment of the text within the lines of the paragraph.
      * @param textDirection The algorithm to be used to resolve the final text and paragraph
      * direction: Left To Right or Right To Left. If no value is provided the system will use the
@@ -291,6 +294,7 @@
         background: Color = Color.Unspecified,
         textDecoration: TextDecoration? = null,
         shadow: Shadow? = null,
+        drawStyle: DrawStyle? = null,
         textAlign: TextAlign? = null,
         textDirection: TextDirection? = null,
         lineHeight: TextUnit = TextUnit.Unspecified,
@@ -315,7 +319,8 @@
             background = background,
             textDecoration = textDecoration,
             shadow = shadow,
-            platformStyle = platformStyle?.spanStyle
+            platformStyle = platformStyle?.spanStyle,
+            drawStyle = drawStyle
         ),
         ParagraphStyle(
             textAlign = textAlign,
@@ -357,6 +362,8 @@
      * @param background The background color for the text.
      * @param textDecoration The decorations to paint on the text (e.g., an underline).
      * @param shadow The shadow effect applied on the text.
+     * @param drawStyle Drawing style of text, whether fill in the text while drawing or stroke
+     * around the edges.
      * @param textAlign The alignment of the text within the lines of the paragraph.
      * @param textDirection The algorithm to be used to resolve the final text and paragraph
      * direction: Left To Right or Right To Left. If no value is provided the system will use the
@@ -387,6 +394,7 @@
         background: Color = Color.Unspecified,
         textDecoration: TextDecoration? = null,
         shadow: Shadow? = null,
+        drawStyle: DrawStyle? = null,
         textAlign: TextAlign? = null,
         textDirection: TextDirection? = null,
         lineHeight: TextUnit = TextUnit.Unspecified,
@@ -412,7 +420,8 @@
             background = background,
             textDecoration = textDecoration,
             shadow = shadow,
-            platformStyle = platformStyle?.spanStyle
+            platformStyle = platformStyle?.spanStyle,
+            drawStyle = drawStyle
         ),
         ParagraphStyle(
             textAlign = textAlign,
@@ -536,7 +545,8 @@
                 background = background,
                 textDecoration = textDecoration,
                 shadow = shadow,
-                platformStyle = this.spanStyle.platformStyle
+                platformStyle = this.spanStyle.platformStyle,
+                drawStyle = this.spanStyle.drawStyle
             ),
             paragraphStyle = ParagraphStyle(
                 textAlign = textAlign,
@@ -628,6 +638,7 @@
         background: Color = this.spanStyle.background,
         textDecoration: TextDecoration? = this.spanStyle.textDecoration,
         shadow: Shadow? = this.spanStyle.shadow,
+        drawStyle: DrawStyle? = this.spanStyle.drawStyle,
         textAlign: TextAlign? = this.paragraphStyle.textAlign,
         textDirection: TextDirection? = this.paragraphStyle.textDirection,
         lineHeight: TextUnit = this.paragraphStyle.lineHeight,
@@ -657,7 +668,8 @@
                 background = background,
                 textDecoration = textDecoration,
                 shadow = shadow,
-                platformStyle = platformStyle?.spanStyle
+                platformStyle = platformStyle?.spanStyle,
+                drawStyle = drawStyle
             ),
             paragraphStyle = ParagraphStyle(
                 textAlign = textAlign,
@@ -690,6 +702,7 @@
         background: Color = this.spanStyle.background,
         textDecoration: TextDecoration? = this.spanStyle.textDecoration,
         shadow: Shadow? = this.spanStyle.shadow,
+        drawStyle: DrawStyle? = this.spanStyle.drawStyle,
         textAlign: TextAlign? = this.paragraphStyle.textAlign,
         textDirection: TextDirection? = this.paragraphStyle.textDirection,
         lineHeight: TextUnit = this.paragraphStyle.lineHeight,
@@ -716,7 +729,8 @@
                 background = background,
                 textDecoration = textDecoration,
                 shadow = shadow,
-                platformStyle = platformStyle?.spanStyle
+                platformStyle = platformStyle?.spanStyle,
+                drawStyle = drawStyle
             ),
             paragraphStyle = ParagraphStyle(
                 textAlign = textAlign,
@@ -825,6 +839,14 @@
     val shadow: Shadow? get() = this.spanStyle.shadow
 
     /**
+     * Drawing style of text, whether fill in the text while drawing or stroke around the edges.
+     */
+    @ExperimentalTextApi
+    @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
+    @get:ExperimentalTextApi
+    val drawStyle: DrawStyle? get() = this.spanStyle.drawStyle
+
+    /**
      * The alignment of the text within the lines of the paragraph.
      */
     val textAlign: TextAlign? get() = this.paragraphStyle.textAlign
@@ -933,7 +955,9 @@
             "localeList=$localeList, " +
             "background=$background, " +
             "textDecoration=$textDecoration, " +
-            "shadow=$shadow, textAlign=$textAlign, " +
+            "shadow=$shadow, " +
+            "drawStyle=$drawStyle, " +
+            "textAlign=$textAlign, " +
             "textDirection=$textDirection, " +
             "lineHeight=$lineHeight, " +
             "textIndent=$textIndent, " +
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/platform/PlatformMultiParagraphDraw.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/platform/PlatformMultiParagraphDraw.kt
index 8b4c7c3..6024d19 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/platform/PlatformMultiParagraphDraw.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/platform/PlatformMultiParagraphDraw.kt
@@ -19,6 +19,7 @@
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.graphics.Shadow
+import androidx.compose.ui.graphics.drawscope.DrawStyle
 import androidx.compose.ui.text.MultiParagraph
 import androidx.compose.ui.text.style.TextDecoration
 
@@ -36,5 +37,6 @@
     brush: Brush,
     alpha: Float = Float.NaN,
     shadow: Shadow? = null,
-    decoration: TextDecoration? = null
+    decoration: TextDecoration? = null,
+    drawStyle: DrawStyle? = null
 )
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaMultiParagraphDraw.skiko.kt b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaMultiParagraphDraw.skiko.kt
index c16fb8b..6bdd632 100644
--- a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaMultiParagraphDraw.skiko.kt
+++ b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaMultiParagraphDraw.skiko.kt
@@ -19,6 +19,7 @@
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.graphics.Shadow
+import androidx.compose.ui.graphics.drawscope.DrawStyle
 import androidx.compose.ui.text.ExperimentalTextApi
 import androidx.compose.ui.text.MultiParagraph
 import androidx.compose.ui.text.style.TextDecoration
@@ -30,11 +31,12 @@
     brush: Brush,
     alpha: Float,
     shadow: Shadow?,
-    decoration: TextDecoration?
+    decoration: TextDecoration?,
+    drawStyle: DrawStyle?
 ) {
     canvas.save()
     paragraphInfoList.fastForEach {
-        it.paragraph.paint(canvas, brush, alpha, shadow, decoration)
+        it.paragraph.paint(canvas, brush, alpha, shadow, decoration, drawStyle)
         canvas.translate(0f, it.paragraph.height)
     }
     canvas.restore()
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/SpanStyleTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/SpanStyleTest.kt
index 0286047..3a3d0bf 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/SpanStyleTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/SpanStyleTest.kt
@@ -19,6 +19,9 @@
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.graphics.drawscope.Fill
+import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.graphics.lerp
 import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.font.FontStyle
@@ -56,6 +59,7 @@
         assertThat(style.background).isEqualTo(Color.Unspecified)
         assertThat(style.textDecoration).isNull()
         assertThat(style.fontFamily).isNull()
+        assertThat(style.drawStyle).isNull()
     }
 
     @OptIn(ExperimentalTextApi::class)
@@ -200,6 +204,15 @@
     }
 
     @Test
+    fun `constructor with customized drawStyle`() {
+        val stroke = Stroke(width = 4f)
+
+        val style = SpanStyle(drawStyle = stroke)
+
+        assertThat(style.drawStyle).isEqualTo(stroke)
+    }
+
+    @Test
     fun `merge with empty other should return this`() {
         val style = SpanStyle()
 
@@ -506,6 +519,28 @@
     }
 
     @Test
+    fun `merge with other's drawStyle is null should use this' drawStyle`() {
+        val drawStyle1 = Stroke(cap = StrokeCap.Butt)
+        val style = SpanStyle(drawStyle = drawStyle1)
+
+        val newSpanStyle = style.merge(SpanStyle(drawStyle = null))
+
+        assertThat(newSpanStyle.drawStyle).isEqualTo(drawStyle1)
+    }
+
+    @Test
+    fun `merge with other's drawStyle is set should use other's drawStyle`() {
+        val drawStyle1 = Stroke(cap = StrokeCap.Butt)
+        val drawStyle2 = Fill
+        val style = SpanStyle(drawStyle = drawStyle1)
+        val otherStyle = SpanStyle(drawStyle = drawStyle2)
+
+        val newSpanStyle = style.merge(otherStyle)
+
+        assertThat(newSpanStyle.drawStyle).isEqualTo(otherStyle.drawStyle)
+    }
+
+    @Test
     fun `plus operator merges`() {
         val style = SpanStyle(
             color = Color.Red,
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
index d7e0cbc..80dae828 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
@@ -366,6 +366,7 @@
             getProperty("textGeometricTransform"),
             getProperty("localeList"),
             getProperty("background"),
+            getProperty("drawStyle"),
             getProperty("textAlign"),
             getProperty("textDirection"),
             getProperty("lineHeight"),
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleTest.kt
index c7c49dd..234888e 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleTest.kt
@@ -21,6 +21,9 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shadow
 import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.graphics.drawscope.Fill
+import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.graphics.lerp
 import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.font.FontStyle
@@ -32,8 +35,8 @@
 import androidx.compose.ui.text.style.Hyphens
 import androidx.compose.ui.text.style.LineBreak
 import androidx.compose.ui.text.style.LineHeightStyle
-import androidx.compose.ui.text.style.LineHeightStyle.Trim
 import androidx.compose.ui.text.style.LineHeightStyle.Alignment
+import androidx.compose.ui.text.style.LineHeightStyle.Trim
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.text.style.TextDecoration
 import androidx.compose.ui.text.style.TextDirection
@@ -65,6 +68,7 @@
         assertThat(style.letterSpacing.isUnspecified).isTrue()
         assertThat(style.localeList).isNull()
         assertThat(style.background).isEqualTo(Color.Unspecified)
+        assertThat(style.drawStyle).isNull()
         assertThat(style.textDecoration).isNull()
         assertThat(style.fontFamily).isNull()
         assertThat(style.platformStyle).isNull()
@@ -329,6 +333,16 @@
         assertThat(style.lineBreak).isEqualTo(LineBreak.Heading)
     }
 
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun `constructor with customized drawStyle`() {
+        val stroke = Stroke(width = 8f)
+
+        val style = TextStyle(drawStyle = stroke)
+
+        assertThat(style.drawStyle).isEqualTo(stroke)
+    }
+
     @Test
     fun `merge with empty other should return this`() {
         val style = TextStyle()
@@ -547,6 +561,30 @@
         assertThat(newStyle.textDecoration).isEqualTo(otherStyle.textDecoration)
     }
 
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun `merge with other's drawStyle is null should use this' drawStyle`() {
+        val drawStyle1 = Stroke(cap = StrokeCap.Butt)
+        val style = TextStyle(drawStyle = drawStyle1)
+
+        val newTextStyle = style.merge(TextStyle(drawStyle = null))
+
+        assertThat(newTextStyle.drawStyle).isEqualTo(drawStyle1)
+    }
+
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun `merge with other's drawStyle is set should use other's drawStyle`() {
+        val drawStyle1 = Stroke(cap = StrokeCap.Butt)
+        val drawStyle2 = Fill
+        val style = TextStyle(drawStyle = drawStyle1)
+        val otherStyle = TextStyle(drawStyle = drawStyle2)
+
+        val newTextStyle = style.merge(otherStyle)
+
+        assertThat(newTextStyle.drawStyle).isEqualTo(otherStyle.drawStyle)
+    }
+
     @Test
     fun `merge with other's locale is null should use this' locale`() {
         val style = TextStyle(localeList = LocaleList("en-US"))
@@ -1183,6 +1221,34 @@
         assertThat(newStyle.textDecoration).isEqualTo(decoration2)
     }
 
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun `lerp drawStyle with a and b are not null and fraction is smaller than half`() {
+        val drawStyle1 = Fill
+        val drawStyle2 = Stroke(width = 8f)
+        val t = 0.2f
+        val style1 = TextStyle(drawStyle = drawStyle1)
+        val style2 = TextStyle(drawStyle = drawStyle2)
+
+        val newStyle = lerp(start = style1, stop = style2, fraction = t)
+
+        assertThat(newStyle.drawStyle).isEqualTo(drawStyle1)
+    }
+
+    @OptIn(ExperimentalTextApi::class)
+    @Test
+    fun `lerp drawStyle with a and b are not null and fraction is larger than half`() {
+        val drawStyle1 = Fill
+        val drawStyle2 = Stroke(width = 8f)
+        val t = 0.8f
+        val style1 = TextStyle(drawStyle = drawStyle1)
+        val style2 = TextStyle(drawStyle = drawStyle2)
+
+        val newStyle = lerp(start = style1, stop = style2, fraction = t)
+
+        assertThat(newStyle.drawStyle).isEqualTo(drawStyle2)
+    }
+
     @Test
     fun `lerp textAlign with a null, b not null and t is smaller than half`() {
         val style1 = TextStyle(textAlign = null)
@@ -1475,6 +1541,7 @@
         val background = Color.Yellow
         val decoration = TextDecoration.Underline
         val shadow = Shadow(color = Color.Green, offset = Offset(2f, 4f))
+        val drawStyle = Stroke(width = 8f)
 
         val style = TextStyle(
             brush = brush,
@@ -1490,7 +1557,8 @@
             localeList = localeList,
             background = background,
             textDecoration = decoration,
-            shadow = shadow
+            shadow = shadow,
+            drawStyle = drawStyle
         )
 
         assertThat(style.toSpanStyle()).isEqualTo(
@@ -1508,7 +1576,8 @@
                 localeList = localeList,
                 background = background,
                 textDecoration = decoration,
-                shadow = shadow
+                shadow = shadow,
+                drawStyle = drawStyle
             )
         )
     }