[go: nahoru, domu]

Do text layout during Paragraph construction

Removes Paragraph.layout function in order to make the object immutable. After
this CL whenever a Paragraph or MultiParagraph is created the text is laid out
during construction.

Test: ./gradlew ui:ui-text:connectedAndroidTest
Test: ./gradlew ui:ui-text:test
Test: ./gradlew ui:integration-tests-benchmark:combileDebugAndroid

Bug: 141135463
Change-Id: I1490f96b99ebde8072b9d44d50db49adc619ec7e
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
index c521776..8c10b94 100644
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/MultiParagraphIntegrationTest.kt
@@ -36,7 +36,6 @@
 import androidx.ui.text.style.TextDirection
 import androidx.ui.text.style.TextDirectionAlgorithm
 import androidx.ui.text.style.TextIndent
-import com.nhaarman.mockitokotlin2.mock
 import org.hamcrest.Matchers.equalTo
 import org.junit.Assert.assertThat
 import org.junit.Test
@@ -57,9 +56,11 @@
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
             val text = ""
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = 100.0f))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = 100.0f)
+            )
 
             assertThat(paragraph.width, equalTo(100.0f))
 
@@ -79,10 +80,12 @@
             val fontSizeInPx = fontSize.toPx().value
 
             for (text in arrayOf("xyz", "\u05D0\u05D1\u05D2")) {
-                val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-                // width greater than text width - 150
-                paragraph.layout(ParagraphConstraints(width = 200.0f))
+                val paragraph = simpleMultiParagraph(
+                    text = text,
+                    fontSize = fontSize,
+                    // width greater than text width - 150
+                    constraints = ParagraphConstraints(width = 200.0f)
+                )
 
                 assertThat(text, paragraph.width, equalTo(200.0f))
                 assertThat(text, paragraph.height, equalTo(fontSizeInPx))
@@ -94,7 +97,8 @@
                     paragraph.maxIntrinsicWidth,
                     equalTo(fontSizeInPx * text.length)
                 )
-                assertThat(text, paragraph.minIntrinsicWidth,
+                assertThat(
+                    text, paragraph.minIntrinsicWidth,
                     equalTo(text.length * fontSizeInPx)
                 )
             }
@@ -108,10 +112,12 @@
             val fontSizeInPx = fontSize.toPx().value
 
             for (text in arrayOf("abcdef", "\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5")) {
-                val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-                // 3 chars width
-                paragraph.layout(ParagraphConstraints(width = 3 * fontSizeInPx))
+                val paragraph = simpleMultiParagraph(
+                    text = text,
+                    fontSize = fontSize,
+                    // 3 chars width
+                    constraints = ParagraphConstraints(width = 3 * fontSizeInPx)
+                )
 
                 // 3 chars
                 assertThat(text, paragraph.width, equalTo(3 * fontSizeInPx))
@@ -142,9 +148,12 @@
     fun didExceedMaxLines_withMaxLinesSmallerThanTextLines_returnsTrue() {
         val text = "aaa\naa"
         val maxLines = text.lines().size - 1
-        val paragraph = simpleMultiParagraph(text = text, maxLines = maxLines)
+        val paragraph = simpleMultiParagraph(
+            text = text,
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
         assertThat(paragraph.didExceedMaxLines, equalTo(true))
     }
 
@@ -152,9 +161,12 @@
     fun didExceedMaxLines_withMaxLinesEqualToTextLines_returnsFalse() {
         val text = "aaa\naa"
         val maxLines = text.lines().size
-        val paragraph = simpleMultiParagraph(text = text, maxLines = maxLines)
+        val paragraph = simpleMultiParagraph(
+            text = text,
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
         assertThat(paragraph.didExceedMaxLines, equalTo(false))
     }
 
@@ -162,9 +174,12 @@
     fun didExceedMaxLines_withMaxLinesGreaterThanTextLines_returnsFalse() {
         val text = "aaa\naa"
         val maxLines = text.lines().size + 1
-        val paragraph = simpleMultiParagraph(text = text, maxLines = maxLines)
+        val paragraph = simpleMultiParagraph(
+            text = text,
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
         assertThat(paragraph.didExceedMaxLines, equalTo(false))
     }
 
@@ -178,11 +193,11 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                maxLines = maxLines
+                maxLines = maxLines,
+                // One line can only contain 1 character
+                constraints = ParagraphConstraints(width = fontSizeInPx)
             )
 
-            // One line can only contain 1 character
-            paragraph.layout(ParagraphConstraints(width = fontSizeInPx))
             assertThat(paragraph.didExceedMaxLines, equalTo(true))
         }
     }
@@ -191,9 +206,13 @@
     fun didExceedMaxLines_withMaxLinesEqualToTextLines_withLineWrap_returnsFalse() {
         val text = "a"
         val maxLines = text.lines().size
-        val paragraph = simpleMultiParagraph(text = text, fontSize = 50.sp, maxLines = maxLines)
+        val paragraph = simpleMultiParagraph(
+            text = text,
+            fontSize = 50.sp,
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
         assertThat(paragraph.didExceedMaxLines, equalTo(false))
     }
 
@@ -207,11 +226,11 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                maxLines = maxLines
+                maxLines = maxLines,
+                // One line can only contain 1 character
+                constraints = ParagraphConstraints(width = fontSizeInPx)
             )
 
-            // One line can only contain 1 character
-            paragraph.layout(ParagraphConstraints(width = fontSizeInPx))
             assertThat(paragraph.didExceedMaxLines, equalTo(false))
         }
     }
@@ -222,9 +241,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
             // test positions that are 1, fontSize+1, 2fontSize+1 which maps to chars 0, 1, 2 ...
             for (i in 0..text.length) {
                 val position = PxPosition((i * fontSizeInPx + 1).px, (fontSizeInPx / 2).px)
@@ -244,9 +266,11 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             // test positions that are 1, fontSize+1, 2fontSize+1 which maps to chars .., 2, 1, 0
             for (i in 0..text.length) {
@@ -269,9 +293,11 @@
             val text = firstLine + secondLine
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = firstLine.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = firstLine.length * fontSizeInPx)
+            )
 
             // test positions are 1, fontSize+1, 2fontSize+1 and always on the second line
             // which maps to chars 3, 4, 5
@@ -295,9 +321,11 @@
             val text = firstLine + secondLine
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = firstLine.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = firstLine.length * fontSizeInPx)
+            )
 
             // test positions are 1, fontSize+1, 2fontSize+1 and always on the second line
             // which maps to chars 5, 4, 3
@@ -319,9 +347,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             // greater than width
             var position = PxPosition((fontSizeInPx * text.length * 2).px, (fontSizeInPx / 2).px)
@@ -341,9 +371,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             // greater than height
             var position = PxPosition((fontSizeInPx / 2).px, (fontSizeInPx * text.length * 2).px)
@@ -363,9 +395,11 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             assertThat(
                 paragraph.getOffsetForPosition(PxPosition((3 * fontSizeInPx).px, 0.px)),
@@ -390,11 +424,10 @@
                 fontSize = fontSize,
                 paragraphStyles = listOf(
                     AnnotatedString.Item(ParagraphStyle(), 0, 3)
-                )
+                ),
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
             )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
-
             for (i in 0 until 3) {
                 assertThat(
                     paragraph.getOffsetForPosition(PxPosition((i * fontSizeInPx).px, 0.px)),
@@ -419,10 +452,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 val box = paragraph.getBoundingBox(i)
                 assertThat(box.left, equalTo(i * fontSizeInPx))
                 assertThat(box.right, equalTo((i + 1) * fontSizeInPx))
@@ -440,13 +476,15 @@
             val text = firstLine + secondLine
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = firstLine.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = firstLine.length * fontSizeInPx)
+            )
 
             // test positions are 3, 4, 5 and always on the second line
             // which maps to chars 3, 4, 5
-            for (i in 0..secondLine.length - 1) {
+            for (i in secondLine.indices) {
                 val textPosition = i + firstLine.length
                 val box = paragraph.getBoundingBox(textPosition)
                 assertThat(box.left, equalTo(i * fontSizeInPx))
@@ -463,8 +501,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             paragraph.getBoundingBox(-1)
         }
@@ -477,9 +518,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             val textPosition = text.length + 1
             paragraph.getBoundingBox(textPosition)
@@ -492,9 +535,10 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text, fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             paragraph.getCursorRect(text.length + 1)
         }
@@ -506,9 +550,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             paragraph.getCursorRect(-1)
         }
@@ -520,21 +566,25 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
-
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 val cursorRect = paragraph.getCursorRect(i)
                 val cursorXOffset = i * fontSizeInPx
                 assertThat(
                     cursorRect,
-                    equalTo(Rect(
-                        left = cursorXOffset - cursorWidth / 2,
-                        top = 0f,
-                        right = cursorXOffset + cursorWidth / 2,
-                        bottom = fontSizeInPx
-                    ))
+                    equalTo(
+                        Rect(
+                            left = cursorXOffset - cursorWidth / 2,
+                            top = 0f,
+                            right = cursorXOffset + cursorWidth / 2,
+                            bottom = fontSizeInPx
+                        )
+                    )
                 )
             }
         }
@@ -546,21 +596,25 @@
             val text = "abcdef"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val charsPerLine = 3
-
-            paragraph.layout(ParagraphConstraints(width = charsPerLine * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = charsPerLine * fontSizeInPx)
+            )
 
             for (i in 0 until charsPerLine) {
                 val cursorXOffset = i * fontSizeInPx
                 assertThat(
                     paragraph.getCursorRect(i),
-                    equalTo(Rect(
-                        left = cursorXOffset - cursorWidth / 2,
-                        top = 0f,
-                        right = cursorXOffset + cursorWidth / 2,
-                        bottom = fontSizeInPx
-                    ))
+                    equalTo(
+                        Rect(
+                            left = cursorXOffset - cursorWidth / 2,
+                            top = 0f,
+                            right = cursorXOffset + cursorWidth / 2,
+                            bottom = fontSizeInPx
+                        )
+                    )
                 )
             }
 
@@ -568,12 +622,14 @@
                 val cursorXOffset = (i % charsPerLine) * fontSizeInPx
                 assertThat(
                     paragraph.getCursorRect(i),
-                    equalTo(Rect(
-                        left = cursorXOffset - cursorWidth / 2,
-                        top = fontSizeInPx,
-                        right = cursorXOffset + cursorWidth / 2,
-                        bottom = fontSizeInPx * 2.2f
-                    ))
+                    equalTo(
+                        Rect(
+                            left = cursorXOffset - cursorWidth / 2,
+                            top = fontSizeInPx,
+                            right = cursorXOffset + cursorWidth / 2,
+                            bottom = fontSizeInPx * 2.2f
+                        )
+                    )
                 )
             }
         }
@@ -585,20 +641,24 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
-
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 val cursorXOffset = (text.length - i) * fontSizeInPx
                 assertThat(
                     paragraph.getCursorRect(i),
-                    equalTo(Rect(
-                        left = cursorXOffset - cursorWidth / 2,
-                        top = 0f,
-                        right = cursorXOffset + cursorWidth / 2,
-                        bottom = fontSizeInPx
-                    ))
+                    equalTo(
+                        Rect(
+                            left = cursorXOffset - cursorWidth / 2,
+                            top = 0f,
+                            right = cursorXOffset + cursorWidth / 2,
+                            bottom = fontSizeInPx
+                        )
+                    )
                 )
             }
         }
@@ -610,21 +670,25 @@
             val text = "\u05D0\u05D1\u05D2\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val charsPerLine = 3
-
-            paragraph.layout(ParagraphConstraints(width = charsPerLine * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = charsPerLine * fontSizeInPx)
+            )
 
             for (i in 0 until charsPerLine) {
                 val cursorXOffset = (charsPerLine - i) * fontSizeInPx
                 assertThat(
                     paragraph.getCursorRect(i),
-                    equalTo(Rect(
-                        left = cursorXOffset - cursorWidth / 2,
-                        top = 0f,
-                        right = cursorXOffset + cursorWidth / 2,
-                        bottom = fontSizeInPx
-                    ))
+                    equalTo(
+                        Rect(
+                            left = cursorXOffset - cursorWidth / 2,
+                            top = 0f,
+                            right = cursorXOffset + cursorWidth / 2,
+                            bottom = fontSizeInPx
+                        )
+                    )
                 )
             }
 
@@ -632,12 +696,14 @@
                 val cursorXOffset = (charsPerLine - i % charsPerLine) * fontSizeInPx
                 assertThat(
                     paragraph.getCursorRect(i),
-                    equalTo(Rect(
-                        left = cursorXOffset - cursorWidth / 2,
-                        top = fontSizeInPx,
-                        right = cursorXOffset + cursorWidth / 2,
-                        bottom = fontSizeInPx * 2.2f
-                    ))
+                    equalTo(
+                        Rect(
+                            left = cursorXOffset - cursorWidth / 2,
+                            top = fontSizeInPx,
+                            right = cursorXOffset + cursorWidth / 2,
+                            bottom = fontSizeInPx * 2.2f
+                        )
+                    )
                 )
             }
         }
@@ -649,9 +715,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             for (i in 0..text.length) {
                 assertThat(
@@ -668,10 +736,12 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             for (i in 0..text.length) {
                 assertThat(
@@ -690,10 +760,12 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             for (i in 0..ltrText.length) {
                 assertThat(
@@ -722,13 +794,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(0), equalTo(width))
 
@@ -749,13 +821,13 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(0), equalTo(0f))
 
@@ -778,14 +850,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..ltrText.length) {
                 assertThat(
@@ -816,14 +887,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(0), equalTo(width))
             // Notice that abc is
@@ -849,10 +919,12 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             assertThat(paragraph.getPrimaryHorizontal(text.length), equalTo(0f))
         }
@@ -864,10 +936,12 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             assertThat(paragraph.getPrimaryHorizontal(text.length), equalTo(0f))
         }
@@ -879,14 +953,13 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(text.length), equalTo(width))
         }
@@ -898,14 +971,13 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(text.length), equalTo(0f))
         }
@@ -917,9 +989,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             for (i in 0..text.length) {
                 assertThat(
@@ -936,10 +1010,12 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             for (i in 0..text.length) {
                 assertThat(
@@ -958,12 +1034,14 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(
                     paragraph.getSecondaryHorizontal(i),
                     equalTo(fontSizeInPx * i)
@@ -985,13 +1063,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getSecondaryHorizontal(0), equalTo(0f))
 
@@ -1012,13 +1090,13 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getSecondaryHorizontal(0), equalTo(width))
 
@@ -1041,23 +1119,22 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(
                     paragraph.getSecondaryHorizontal(i),
                     equalTo(fontSizeInPx * i)
                 )
             }
 
-            for (i in 0 until rtlText.length) {
+            for (i in rtlText.indices) {
                 assertThat(
                     paragraph.getSecondaryHorizontal(i + ltrText.length),
                     equalTo(width - fontSizeInPx * i)
@@ -1079,14 +1156,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(
                 paragraph.getSecondaryHorizontal(0),
@@ -1114,10 +1190,12 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             assertThat(paragraph.getSecondaryHorizontal(text.length), equalTo(0f))
         }
@@ -1129,10 +1207,12 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             assertThat(paragraph.getSecondaryHorizontal(text.length), equalTo(0f))
         }
@@ -1144,14 +1224,13 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getSecondaryHorizontal(text.length), equalTo(width))
         }
@@ -1163,14 +1242,13 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getSecondaryHorizontal(text.length), equalTo(0f))
         }
@@ -1182,13 +1260,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Ltr))
@@ -1202,14 +1279,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Rtl))
@@ -1223,15 +1299,14 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Rtl))
             }
         }
@@ -1243,14 +1318,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Ltr))
@@ -1266,13 +1340,12 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Ltr))
@@ -1288,14 +1361,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Ltr))
@@ -1311,14 +1383,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Rtl))
@@ -1332,13 +1403,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
@@ -1352,14 +1422,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
@@ -1373,15 +1442,14 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Rtl))
             }
         }
@@ -1393,14 +1461,13 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0 until text.length - 1) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Rtl))
@@ -1417,15 +1484,14 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
             }
 
@@ -1443,16 +1509,15 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
             }
 
@@ -1470,16 +1535,15 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
             }
 
@@ -1495,10 +1559,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             for (i in 0..text.lastIndex) {
                 assertThat(paragraph.getLineForOffset(i), equalTo(0))
@@ -1512,10 +1578,12 @@
             val text = "a\nb\nc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             for (i in 0..text.lastIndex) {
                 assertThat(paragraph.getLineForOffset(i), equalTo(i / 2))
@@ -1529,14 +1597,14 @@
             val text = "abcd"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                paragraphStyles = listOf(AnnotatedString.Item(ParagraphStyle(), 0, 2))
+                paragraphStyles = listOf(AnnotatedString.Item(ParagraphStyle(), 0, 2)),
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
             assertThat(paragraph.getLineForOffset(0), equalTo(0))
             assertThat(paragraph.getLineForOffset(1), equalTo(0))
             assertThat(paragraph.getLineForOffset(2), equalTo(1))
@@ -1550,14 +1618,14 @@
             val text = "abcd"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                paragraphStyles = listOf(AnnotatedString.Item(ParagraphStyle(), 2, 2))
+                paragraphStyles = listOf(AnnotatedString.Item(ParagraphStyle(), 2, 2)),
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
             assertThat(paragraph.getLineForOffset(0), equalTo(0))
             assertThat(paragraph.getLineForOffset(1), equalTo(0))
             // The empty paragraph takes one line
@@ -1572,10 +1640,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             paragraph.getLineForOffset(-1)
         }
@@ -1587,10 +1657,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleMultiParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleMultiParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             paragraph.getLineForOffset(text.length)
         }
@@ -1605,9 +1677,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -1638,9 +1710,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val firstLineLeft = paragraph.getLineLeft(0)
@@ -1685,9 +1757,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -1724,9 +1796,9 @@
         val paragraph = simpleMultiParagraph(
             text = text,
             fontFamily = fontFamilyMeasureFont,
-            fontSize = 20.sp
+            fontSize = 20.sp,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val actualPath = paragraph.getPathForRange(1, 1)
 
@@ -1739,9 +1811,9 @@
         val paragraph = simpleMultiParagraph(
             text = text,
             fontFamily = fontFamilyMeasureFont,
-            fontSize = 20.sp
+            fontSize = 20.sp,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val actualPath = paragraph.getPathForRange(0, 0)
 
@@ -1757,9 +1829,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineRight = paragraph.getLineRight(0)
@@ -1782,9 +1854,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineRight = paragraph.getLineRight(0)
@@ -1807,9 +1879,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineRight = paragraph.getLineRight(0)
@@ -1832,9 +1904,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -1865,9 +1937,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -1891,9 +1963,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -1914,9 +1986,9 @@
         val paragraph = simpleMultiParagraph(
             text = text,
             fontFamily = fontFamilyMeasureFont,
-            fontSize = 20.sp
+            fontSize = 20.sp,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val result = paragraph.getWordBoundary(text.indexOf('a'))
 
@@ -1930,9 +2002,9 @@
         val paragraph = simpleMultiParagraph(
             text = text,
             fontFamily = fontFamilyMeasureFont,
-            fontSize = 20.sp
+            fontSize = 20.sp,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val resultEnglish = paragraph.getWordBoundary(text.indexOf('a'))
         val resultHebrew = paragraph.getWordBoundary(text.indexOf('\u05d1'))
@@ -1943,75 +2015,15 @@
         assertThat(resultHebrew.end, equalTo(text.indexOf('\u05d2') + 1))
     }
 
-    @Test(expected = IllegalStateException::class)
-    fun width_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleMultiParagraph()
-
-        paragraph.width
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun height_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleMultiParagraph()
-
-        paragraph.height
-    }
-
-    @Test
-    fun minIntrinsicWidth_default_value() {
-        val paragraph = simpleMultiParagraph()
-
-        assertThat(paragraph.minIntrinsicWidth, equalTo(0.0f))
-    }
-
-    @Test
-    fun maxIntrinsicWidth_default_value() {
-        val paragraph = simpleMultiParagraph()
-
-        assertThat(paragraph.maxIntrinsicWidth, equalTo(0.0f))
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun firstBaseline_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleMultiParagraph()
-
-        paragraph.firstBaseline
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun lastBaseline_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleMultiParagraph()
-
-        paragraph.lastBaseline
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun didExceedMaxLines_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleMultiParagraph()
-
-        paragraph.didExceedMaxLines
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun paint_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleMultiParagraph()
-
-        paragraph.paint(mock())
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun getPositionForOffset_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleMultiParagraph()
-
-        paragraph.getOffsetForPosition(PxPosition.Origin)
-    }
-
     @Test(expected = AssertionError::class)
     fun getPathForRange_throws_exception_if_start_larger_than_end() {
         val text = "ab"
         val textStart = 0
         val textEnd = text.length
-        val paragraph = simpleMultiParagraph(text = text)
+        val paragraph = simpleMultiParagraph(
+            text = text,
+            constraints = ParagraphConstraints(Float.MAX_VALUE)
+        )
 
         paragraph.getPathForRange(textEnd, textStart)
     }
@@ -2021,7 +2033,10 @@
         val text = "ab"
         val textStart = 0
         val textEnd = text.length
-        val paragraph = simpleMultiParagraph(text = text)
+        val paragraph = simpleMultiParagraph(
+            text = text,
+            constraints = ParagraphConstraints(Float.MAX_VALUE)
+        )
 
         paragraph.getPathForRange(textStart - 2, textEnd - 1)
     }
@@ -2031,7 +2046,10 @@
         val text = "ab"
         val textStart = 0
         val textEnd = text.length
-        val paragraph = simpleMultiParagraph(text = text)
+        val paragraph = simpleMultiParagraph(
+            text = text,
+            constraints = ParagraphConstraints(Float.MAX_VALUE)
+        )
 
         paragraph.getPathForRange(textStart, textEnd + 1)
     }
@@ -2044,19 +2062,19 @@
             val fontSize = 20.sp
             val fontSizeInPx = fontSize.toPx().value
 
+            val layoutLTRWidth = (textLTR.length + 2) * fontSizeInPx
             val paragraphLTR = simpleMultiParagraph(
                 text = textLTR,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutLTRWidth)
             )
-            val layoutLTRWidth = (textLTR.length + 2) * fontSizeInPx
-            paragraphLTR.layout(ParagraphConstraints(width = layoutLTRWidth))
 
+            val layoutRTLWidth = (textRTL.length + 2) * fontSizeInPx
             val paragraphRTL = simpleMultiParagraph(
                 text = textRTL,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutRTLWidth)
             )
-            val layoutRTLWidth = (textRTL.length + 2) * fontSizeInPx
-            paragraphRTL.layout(ParagraphConstraints(width = layoutRTLWidth))
 
             // When textAlign is TextAlign.start, LTR aligns to left, RTL aligns to right.
             assertThat(paragraphLTR.getLineLeft(0), equalTo(0.0f))
@@ -2072,13 +2090,13 @@
             val fontSizeInPx = fontSize.toPx().value
 
             texts.map { text ->
+                val layoutWidth = (text.length + 2) * fontSizeInPx
                 val paragraph = simpleMultiParagraph(
                     text = text,
                     textAlign = TextAlign.Left,
-                    fontSize = fontSize
+                    fontSize = fontSize,
+                    constraints = ParagraphConstraints(width = layoutWidth)
                 )
-                val layoutWidth = (text.length + 2) * fontSizeInPx
-                paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
                 assertThat(paragraph.getLineLeft(0), equalTo(0.0f))
             }
@@ -2093,13 +2111,13 @@
             val fontSizeInPx = fontSize.toPx().value
 
             texts.map { text ->
+                val layoutWidth = (text.length + 2) * fontSizeInPx
                 val paragraph = simpleMultiParagraph(
                     text = text,
                     textAlign = TextAlign.Right,
-                    fontSize = fontSize
+                    fontSize = fontSize,
+                    constraints = ParagraphConstraints(width = layoutWidth)
                 )
-                val layoutWidth = (text.length + 2) * fontSizeInPx
-                paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
                 assertThat(paragraph.getLineRight(0), equalTo(layoutWidth))
             }
@@ -2114,15 +2132,15 @@
             val fontSizeInPx = fontSize.toPx().value
 
             texts.map { text ->
+                val layoutWidth = (text.length + 2) * fontSizeInPx
                 val paragraph = simpleMultiParagraph(
                     text = text,
                     textAlign = TextAlign.Center,
-                    fontSize = fontSize
+                    fontSize = fontSize,
+                    constraints = ParagraphConstraints(width = layoutWidth)
                 )
-                val layoutWidth = (text.length + 2) * fontSizeInPx
-                paragraph.layout(ParagraphConstraints(width = layoutWidth))
-                val textWidth = text.length * fontSizeInPx
 
+                val textWidth = text.length * fontSizeInPx
                 assertThat(
                     paragraph.getLineLeft(0),
                     equalTo(layoutWidth / 2 - textWidth / 2)
@@ -2146,9 +2164,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 textAlign = TextAlign.Start,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineLeft(0), equalTo(0.0f))
         }
@@ -2165,9 +2183,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 textAlign = TextAlign.End,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineRight(0), equalTo(layoutWidth))
         }
@@ -2184,9 +2202,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 textAlign = TextAlign.Start,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineRight(0), equalTo(layoutWidth))
         }
@@ -2203,9 +2221,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 textAlign = TextAlign.End,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineLeft(0), equalTo(0.0f))
         }
@@ -2225,9 +2243,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 textAlign = TextAlign.Justify,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineLeft(0), equalTo(0.0f))
             assertThat(paragraph.getLineRight(0), equalTo(layoutWidth))
@@ -2247,9 +2265,10 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
+
             // The position of the last character in display order.
             val position = PxPosition(("a.".length * fontSizeInPx + 1).px, (fontSizeInPx / 2).px)
             val charIndex = paragraph.getOffsetForPosition(position)
@@ -2268,9 +2287,10 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
+
             // The position of the first character in display order.
             val position = PxPosition((fontSizeInPx / 2 + 1).px, (fontSizeInPx / 2).px)
             val charIndex = paragraph.getOffsetForPosition(position)
@@ -2288,9 +2308,10 @@
 
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
+
             for (i in 0..text.length) {
                 // The position of the i-th character in display order.
                 val position = PxPosition((i * fontSizeInPx + 1).px, (fontSizeInPx / 2).px)
@@ -2310,10 +2331,11 @@
 
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
-            for (i in 0 until text.length) {
+
+            for (i in text.indices) {
                 // The position of the i-th character in display order.
                 val position = PxPosition((i * fontSizeInPx + 1).px, (fontSizeInPx / 2).px)
                 val charIndex = paragraph.getOffsetForPosition(position)
@@ -2332,9 +2354,10 @@
 
             val paragraph = simpleMultiParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
+
             // The first character in display order should be '.'
             val position = PxPosition((fontSizeInPx / 2 + 1).px, (fontSizeInPx / 2).px)
             val index = paragraph.getOffsetForPosition(position)
@@ -2355,9 +2378,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                lineHeight = lineHeight
+                lineHeight = lineHeight,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.lineCount, equalTo(4))
             // TODO(Migration/haoyuchang): Due to bug b/120530738, the height of the first line is
@@ -2387,9 +2410,9 @@
             val paragraph = simpleMultiParagraph(
                 text = text,
                 fontSize = fontSize,
-                lineHeight = lineHeight
+                lineHeight = lineHeight,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             val lastLine = paragraph.lineCount - 1
             // In the sample_font.ttf, the height of the line should be
@@ -2410,9 +2433,9 @@
                 text = text,
                 textIndent = TextIndent(firstLine = indent.px),
                 fontSize = fontSize,
-                fontFamily = fontFamilyMeasureFont
+                fontFamily = fontFamilyMeasureFont,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             // This position should point to the first character 'a' if indent is applied.
             // Otherwise this position will point to the second character 'b'.
@@ -2435,9 +2458,9 @@
                 text = text,
                 textIndent = TextIndent(firstLine = indent.px),
                 fontSize = fontSize,
-                fontFamily = fontFamilyMeasureFont
+                fontFamily = fontFamilyMeasureFont,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             assertThat(paragraph.lineCount, equalTo(2))
             // This position should point to the first character of the first line if indent is
@@ -2464,9 +2487,9 @@
                     restLine = indent.px
                 ),
                 fontSize = fontSize,
-                fontFamily = fontFamilyMeasureFont
+                fontFamily = fontFamilyMeasureFont,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             // This position should point to the first character of the second line if indent is
             // applied. Otherwise this position will point to the second character of the second line.
@@ -2491,6 +2514,7 @@
         fontFamily: FontFamily = fontFamilyMeasureFont,
         localeList: LocaleList? = null,
         textStyle: TextStyle? = null,
+        constraints: ParagraphConstraints,
         density: Density? = null,
         layoutDirection: LayoutDirection = LayoutDirection.Ltr,
         textDirectionAlgorithm: TextDirectionAlgorithm? = null
@@ -2513,6 +2537,7 @@
                 lineHeight = lineHeight
             ),
             maxLines = maxLines,
+            constraints = constraints,
             density = density ?: defaultDensity,
             layoutDirection = layoutDirection,
             resourceLoader = TestFontResourceLoader(context)
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntegrationTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntegrationTest.kt
index d9e5d89..77760aa 100644
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntegrationTest.kt
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/ParagraphIntegrationTest.kt
@@ -28,8 +28,8 @@
 import androidx.ui.core.withDensity
 import androidx.ui.engine.geometry.Offset
 import androidx.ui.engine.geometry.Rect
-import androidx.ui.graphics.Color
 import androidx.ui.graphics.Canvas
+import androidx.ui.graphics.Color
 import androidx.ui.graphics.Image
 import androidx.ui.graphics.ImageConfig
 import androidx.ui.graphics.Path
@@ -53,7 +53,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
-import org.mockito.Mockito.mock
 import kotlin.math.roundToInt
 
 @RunWith(JUnit4::class)
@@ -77,9 +76,11 @@
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
             val text = ""
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = 100.0f))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = 100.0f)
+            )
 
             assertThat(paragraph.width, equalTo(100.0f))
 
@@ -89,8 +90,6 @@
             assertThat(paragraph.lastBaseline, equalTo(fontSizeInPx * 0.8f))
             assertThat(paragraph.maxIntrinsicWidth, equalTo(0.0f))
             assertThat(paragraph.minIntrinsicWidth, equalTo(0.0f))
-            // TODO(Migration/siyamed): no baseline query per line?
-            // TODO(Migration/siyamed): no line count?
         }
     }
 
@@ -101,10 +100,12 @@
             val fontSizeInPx = fontSize.toPx().value
 
             for (text in arrayOf("xyz", "\u05D0\u05D1\u05D2")) {
-                val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-                // width greater than text width - 150
-                paragraph.layout(ParagraphConstraints(width = 200.0f))
+                val paragraph = simpleParagraph(
+                    text = text,
+                    fontSize = fontSize,
+                    // width greater than text width - 150
+                    constraints = ParagraphConstraints(width = 200.0f)
+                )
 
                 assertThat(text, paragraph.width, equalTo(200.0f))
                 assertThat(text, paragraph.height, equalTo(fontSizeInPx))
@@ -128,10 +129,12 @@
             val fontSizeInPx = fontSize.toPx().value
 
             for (text in arrayOf("abcdef", "\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5")) {
-                val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-                // 3 chars width
-                paragraph.layout(ParagraphConstraints(width = 3 * fontSizeInPx))
+                val paragraph = simpleParagraph(
+                    text = text,
+                    fontSize = fontSize,
+                    // 3 chars width
+                    constraints = ParagraphConstraints(width = 3 * fontSizeInPx)
+                )
 
                 // 3 chars
                 assertThat(text, paragraph.width, equalTo(3 * fontSizeInPx))
@@ -165,13 +168,14 @@
             val fontSizeInPx = fontSize.toPx().value
 
             for (text in arrayOf("abc\ndef", "\u05D0\u05D1\u05D2\n\u05D3\u05D4\u05D5")) {
-                val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-                // 3 chars width
-                paragraph.layout(ParagraphConstraints(width = 3 * fontSizeInPx))
+                val paragraph = simpleParagraph(
+                    text = text,
+                    fontSize = fontSize,
+                    // 3 chars width
+                    constraints = ParagraphConstraints(width = 3 * fontSizeInPx)
+                )
 
                 // 3 chars
-
                 assertThat(text, paragraph.width, equalTo(3 * fontSizeInPx))
                 // 2 lines, 1 line gap
                 assertThat(
@@ -205,11 +209,12 @@
             val fontSizeInPx = fontSize.toPx().value
 
             for (text in arrayOf("abc\ndef", "\u05D0\u05D1\u05D2\n\u05D3\u05D4\u05D5")) {
-                val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-                // 2 chars width
-
-                paragraph.layout(ParagraphConstraints(width = 2 * fontSizeInPx))
+                val paragraph = simpleParagraph(
+                    text = text,
+                    fontSize = fontSize,
+                    // 2 chars width
+                    constraints = ParagraphConstraints(width = 2 * fontSizeInPx)
+                )
 
                 // 2 chars
                 assertThat(text, paragraph.width, equalTo(2 * fontSizeInPx))
@@ -244,9 +249,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
             // test positions that are 1, fontSize+1, 2fontSize+1 which maps to chars 0, 1, 2 ...
             for (i in 0..text.length) {
                 val position = PxPosition((i * fontSizeInPx + 1).px, (fontSizeInPx / 2).px)
@@ -266,9 +274,11 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             // test positions that are 1, fontSize+1, 2fontSize+1 which maps to chars .., 2, 1, 0
             for (i in 0..text.length) {
@@ -291,9 +301,11 @@
             val text = firstLine + secondLine
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = firstLine.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = firstLine.length * fontSizeInPx)
+            )
 
             // test positions are 1, fontSize+1, 2fontSize+1 and always on the second line
             // which maps to chars 3, 4, 5
@@ -317,9 +329,11 @@
             val text = firstLine + secondLine
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = firstLine.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = firstLine.length * fontSizeInPx)
+            )
 
             // test positions are 1, fontSize+1, 2fontSize+1 and always on the second line
             // which maps to chars 5, 4, 3
@@ -341,9 +355,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             // greater than width
             var position = PxPosition((fontSizeInPx * text.length * 2).px, (fontSizeInPx / 2).px)
@@ -363,9 +379,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             // greater than height
             var position = PxPosition((fontSizeInPx / 2).px, (fontSizeInPx * text.length * 2).px)
@@ -385,9 +403,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
             // test positions that are 0, 1, 2 ... which maps to chars 0, 1, 2 ...
             for (i in 0..text.length - 1) {
                 val box = paragraph.getBoundingBox(i)
@@ -407,13 +428,15 @@
             val text = firstLine + secondLine
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = firstLine.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = firstLine.length * fontSizeInPx)
+            )
 
             // test positions are 3, 4, 5 and always on the second line
             // which maps to chars 3, 4, 5
-            for (i in 0..secondLine.length - 1) {
+            for (i in secondLine.indices) {
                 val textPosition = i + firstLine.length
                 val box = paragraph.getBoundingBox(textPosition)
                 assertThat(box.left, equalTo(i * fontSizeInPx))
@@ -430,9 +453,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             val textPosition = -1
             val box = paragraph.getBoundingBox(textPosition)
@@ -451,9 +476,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             val textPosition = text.length + 1
             paragraph.getBoundingBox(textPosition)
@@ -466,9 +493,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             paragraph.getCursorRect(text.length + 1)
         }
@@ -480,9 +509,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             paragraph.getCursorRect(-1)
         }
@@ -494,11 +525,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
-
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 val cursorRect = paragraph.getCursorRect(i)
                 val cursorXOffset = i * fontSizeInPx
                 assertThat(
@@ -520,10 +553,12 @@
             val text = "abcdef"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val charsPerLine = 3
-
-            paragraph.layout(ParagraphConstraints(width = charsPerLine * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = charsPerLine * fontSizeInPx)
+            )
 
             for (i in 0 until charsPerLine) {
                 val cursorXOffset = i * fontSizeInPx
@@ -559,9 +594,11 @@
             val text = "abc\ndef"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+            )
 
             // Cursor before '\n'
             assertThat(
@@ -593,9 +630,11 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+            )
 
             // Cursor before '\n'
             assertThat(
@@ -627,11 +666,13 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
-
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 val cursorXOffset = (text.length - i) * fontSizeInPx
                 assertThat(
                     paragraph.getCursorRect(i),
@@ -652,10 +693,12 @@
             val text = "\u05D0\u05D1\u05D2\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val charsPerLine = 3
-
-            paragraph.layout(ParagraphConstraints(width = charsPerLine * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = charsPerLine * fontSizeInPx)
+            )
 
             for (i in 0 until charsPerLine) {
                 val cursorXOffset = (charsPerLine - i) * fontSizeInPx
@@ -691,9 +734,11 @@
             val text = "\u05D0\u05D1\u05D2\n\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = 3 * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = 3 * fontSizeInPx)
+            )
 
             // Cursor before '\n'
             assertThat(
@@ -725,9 +770,11 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = 3 * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = 3 * fontSizeInPx)
+            )
 
             // Cursor before '\n'
             assertThat(
@@ -759,9 +806,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             for (i in 0..text.length) {
                 assertThat(
@@ -778,10 +827,12 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             for (i in 0..text.length) {
                 assertThat(
@@ -800,10 +851,12 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             for (i in 0..ltrText.length) {
                 assertThat(
@@ -832,13 +885,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(0), equalTo(width))
 
@@ -859,13 +912,13 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(0), equalTo(0f))
 
@@ -888,14 +941,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..ltrText.length) {
                 assertThat(
@@ -926,14 +978,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(0), equalTo(width))
             for (i in 1 until ltrText.length) {
@@ -958,10 +1009,12 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             assertThat(paragraph.getPrimaryHorizontal(text.length), equalTo(0f))
         }
@@ -973,10 +1026,12 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             assertThat(paragraph.getPrimaryHorizontal(text.length), equalTo(0f))
         }
@@ -988,14 +1043,13 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(text.length), equalTo(width))
         }
@@ -1007,14 +1061,13 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getPrimaryHorizontal(text.length), equalTo(0f))
         }
@@ -1026,9 +1079,11 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
-
-            paragraph.layout(ParagraphConstraints(width = text.length * fontSizeInPx))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = text.length * fontSizeInPx)
+            )
 
             for (i in 0..text.length) {
                 assertThat(
@@ -1045,10 +1100,12 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             for (i in 0..text.length) {
                 assertThat(
@@ -1067,12 +1124,14 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(
                     paragraph.getSecondaryHorizontal(i),
                     equalTo(fontSizeInPx * i)
@@ -1094,13 +1153,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getSecondaryHorizontal(0), equalTo(0f))
 
@@ -1121,13 +1180,13 @@
             val text = "\u05D0\u05D1\u05D2"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getSecondaryHorizontal(0), equalTo(width))
 
@@ -1150,23 +1209,22 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(
                     paragraph.getSecondaryHorizontal(i),
                     equalTo(fontSizeInPx * i)
                 )
             }
 
-            for (i in 0 until rtlText.length) {
+            for (i in rtlText.indices) {
                 assertThat(
                     paragraph.getSecondaryHorizontal(i + ltrText.length),
                     equalTo(width - fontSizeInPx * i)
@@ -1188,14 +1246,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(
                 paragraph.getSecondaryHorizontal(0),
@@ -1223,10 +1280,12 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             assertThat(paragraph.getSecondaryHorizontal(text.length), equalTo(0f))
         }
@@ -1238,10 +1297,12 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize)
             val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
+            )
 
             assertThat(paragraph.getSecondaryHorizontal(text.length), equalTo(0f))
         }
@@ -1253,14 +1314,13 @@
             val text = "abc\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getSecondaryHorizontal(text.length), equalTo(width))
         }
@@ -1272,14 +1332,13 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             assertThat(paragraph.getSecondaryHorizontal(text.length), equalTo(0f))
         }
@@ -1291,13 +1350,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Ltr))
@@ -1311,14 +1369,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Rtl))
@@ -1332,15 +1389,14 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Rtl))
             }
         }
@@ -1352,14 +1408,13 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Ltr))
@@ -1375,13 +1430,12 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Ltr))
@@ -1397,14 +1451,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Ltr))
@@ -1420,14 +1473,13 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getParagraphDirection(i), equalTo(TextDirection.Rtl))
@@ -1441,13 +1493,12 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
@@ -1461,14 +1512,13 @@
             val text = "abc"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0..text.length) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
@@ -1482,15 +1532,14 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until text.length) {
+            for (i in text.indices) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Rtl))
             }
         }
@@ -1502,14 +1551,13 @@
             val text = "\u05D0\u05D1\u05D2\n"
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
-
-            paragraph.layout(ParagraphConstraints(width))
 
             for (i in 0 until text.length - 1) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Rtl))
@@ -1526,15 +1574,14 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
             }
 
@@ -1552,16 +1599,15 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
             }
 
@@ -1579,16 +1625,15 @@
             val text = ltrText + rtlText
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
+            val width = text.length * fontSizeInPx
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl
+                textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
+                constraints = ParagraphConstraints(width)
             )
-            val width = text.length * fontSizeInPx
 
-            paragraph.layout(ParagraphConstraints(width))
-
-            for (i in 0 until ltrText.length) {
+            for (i in ltrText.indices) {
                 assertThat(paragraph.getBidiRunDirection(i), equalTo(TextDirection.Ltr))
             }
 
@@ -1623,12 +1668,11 @@
                     paragraphStyle = ParagraphStyle(),
                     density = defaultDensity,
                     resourceLoader = resourceLoader,
-                    layoutDirection = LayoutDirection.Ltr
+                    layoutDirection = LayoutDirection.Ltr,
+                    // just have 10x font size to have a bitmap
+                    constraints = ParagraphConstraints(width = fontSizeInPx * 10)
                 )
 
-                // just have 10x font size to have a bitmap
-                paragraph.layout(ParagraphConstraints(width = fontSizeInPx * 10))
-
                 paragraph.bitmap()
             }
 
@@ -1647,9 +1691,10 @@
         val paragraph = simpleParagraph(
             text = text,
             fontSize = 100.sp,
-            maxLines = maxLines
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
+
         assertThat(paragraph.height, equalTo(0f))
     }
 
@@ -1657,12 +1702,12 @@
     fun maxLines_withMaxLineNegative_throwsException() {
         val text = "a\na\na"
         val maxLines = -1
-        val paragraph = simpleParagraph(
+        simpleParagraph(
             text = text,
             fontSize = 100.sp,
-            maxLines = maxLines
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
     }
 
     @Test
@@ -1676,9 +1721,10 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                maxLines = maxLines
+                maxLines = maxLines,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
+
             val expectHeight = (maxLines + (maxLines - 1) * 0.2f) * fontSizeInPx
             assertThat(paragraph.height, equalTo(expectHeight))
         }
@@ -1695,9 +1741,10 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                maxLines = maxLines
+                maxLines = maxLines,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
+
             val expectFirstBaseline = 0.8f * fontSizeInPx
             assertThat(paragraph.firstBaseline, equalTo(expectFirstBaseline))
             val expectLastBaseline =
@@ -1716,9 +1763,10 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                maxLines = maxLines
+                maxLines = maxLines,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
+
             val expectHeight = (maxLines + (maxLines - 1) * 0.2f) * fontSizeInPx
             assertThat(paragraph.height, equalTo(expectHeight))
         }
@@ -1735,9 +1783,10 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                maxLines = maxLines
+                maxLines = maxLines,
+                constraints = ParagraphConstraints(width = 200f)
             )
-            paragraph.layout(ParagraphConstraints(width = 200f))
+
             val expectHeight = (lineCount + (lineCount - 1) * 0.2f) * fontSizeInPx
             assertThat(paragraph.height, equalTo(expectHeight))
         }
@@ -1754,15 +1803,15 @@
             val paragraphWithMaxLine = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                maxLines = maxLines
+                maxLines = maxLines,
+                constraints = ParagraphConstraints(width = fontSizeInPx)
             )
-            paragraphWithMaxLine.layout(ParagraphConstraints(width = fontSizeInPx))
 
             val paragraphNoMaxLine = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = fontSizeInPx)
             )
-            paragraphNoMaxLine.layout(ParagraphConstraints(width = fontSizeInPx))
 
             // Make sure the maxLine is applied correctly
             assertThat(paragraphNoMaxLine.height, greaterThan(paragraphWithMaxLine.height))
@@ -1792,9 +1841,12 @@
     fun didExceedMaxLines_withMaxLinesSmallerThanTextLines_returnsTrue() {
         val text = "aaa\naa"
         val maxLines = text.lines().size - 1
-        val paragraph = simpleParagraph(text = text, maxLines = maxLines)
+        val paragraph = simpleParagraph(
+            text = text,
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
         assertThat(paragraph.didExceedMaxLines, equalTo(true))
     }
 
@@ -1802,9 +1854,12 @@
     fun didExceedMaxLines_withMaxLinesEqualToTextLines_returnsFalse() {
         val text = "aaa\naa"
         val maxLines = text.lines().size
-        val paragraph = simpleParagraph(text = text, maxLines = maxLines)
+        val paragraph = simpleParagraph(
+            text = text,
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
         assertThat(paragraph.didExceedMaxLines, equalTo(false))
     }
 
@@ -1812,9 +1867,12 @@
     fun didExceedMaxLines_withMaxLinesGreaterThanTextLines_returnsFalse() {
         val text = "aaa\naa"
         val maxLines = text.lines().size + 1
-        val paragraph = simpleParagraph(text = text, maxLines = maxLines)
+        val paragraph = simpleParagraph(
+            text = text,
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
         assertThat(paragraph.didExceedMaxLines, equalTo(false))
     }
 
@@ -1825,10 +1883,14 @@
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
             val maxLines = 1
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize, maxLines = maxLines)
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                maxLines = maxLines,
+                // One line can only contain 1 character
+                constraints = ParagraphConstraints(width = fontSizeInPx)
+            )
 
-            // One line can only contain 1 character
-            paragraph.layout(ParagraphConstraints(width = fontSizeInPx))
             assertThat(paragraph.didExceedMaxLines, equalTo(true))
         }
     }
@@ -1837,9 +1899,13 @@
     fun didExceedMaxLines_withMaxLinesEqualToTextLines_withLineWrap_returnsFalse() {
         val text = "a"
         val maxLines = text.lines().size
-        val paragraph = simpleParagraph(text = text, fontSize = 50.sp, maxLines = maxLines)
+        val paragraph = simpleParagraph(
+            text = text,
+            fontSize = 50.sp,
+            maxLines = maxLines,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
         assertThat(paragraph.didExceedMaxLines, equalTo(false))
     }
 
@@ -1850,10 +1916,14 @@
             val maxLines = 3
             val fontSize = 50.sp
             val fontSizeInPx = fontSize.toPx().value
-            val paragraph = simpleParagraph(text = text, fontSize = fontSize, maxLines = maxLines)
+            val paragraph = simpleParagraph(
+                text = text,
+                fontSize = fontSize,
+                maxLines = maxLines,
+                // One line can only contain 1 character
+                constraints = ParagraphConstraints(width = fontSizeInPx)
+            )
 
-            // One line can only contain 1 character
-            paragraph.layout(ParagraphConstraints(width = fontSizeInPx))
             assertThat(paragraph.didExceedMaxLines, equalTo(false))
         }
     }
@@ -1866,19 +1936,19 @@
             val fontSize = 20.sp
             val fontSizeInPx = fontSize.toPx().value
 
+            val layoutLTRWidth = (textLTR.length + 2) * fontSizeInPx
             val paragraphLTR = simpleParagraph(
                 text = textLTR,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutLTRWidth)
             )
-            val layoutLTRWidth = (textLTR.length + 2) * fontSizeInPx
-            paragraphLTR.layout(ParagraphConstraints(width = layoutLTRWidth))
 
+            val layoutRTLWidth = (textRTL.length + 2) * fontSizeInPx
             val paragraphRTL = simpleParagraph(
                 text = textRTL,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutRTLWidth)
             )
-            val layoutRTLWidth = (textRTL.length + 2) * fontSizeInPx
-            paragraphRTL.layout(ParagraphConstraints(width = layoutRTLWidth))
 
             // When textAlign is TextAlign.start, LTR aligns to left, RTL aligns to right.
             assertThat(paragraphLTR.getLineLeft(0), equalTo(0.0f))
@@ -1894,13 +1964,13 @@
             val fontSizeInPx = fontSize.toPx().value
 
             texts.map { text ->
+                val layoutWidth = (text.length + 2) * fontSizeInPx
                 val paragraph = simpleParagraph(
                     text = text,
                     textAlign = TextAlign.Left,
-                    fontSize = fontSize
+                    fontSize = fontSize,
+                    constraints = ParagraphConstraints(width = layoutWidth)
                 )
-                val layoutWidth = (text.length + 2) * fontSizeInPx
-                paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
                 assertThat(paragraph.getLineLeft(0), equalTo(0.0f))
             }
@@ -1915,13 +1985,13 @@
             val fontSizeInPx = fontSize.toPx().value
 
             texts.map { text ->
+                val layoutWidth = (text.length + 2) * fontSizeInPx
                 val paragraph = simpleParagraph(
                     text = text,
                     textAlign = TextAlign.Right,
-                    fontSize = fontSize
+                    fontSize = fontSize,
+                    constraints = ParagraphConstraints(width = layoutWidth)
                 )
-                val layoutWidth = (text.length + 2) * fontSizeInPx
-                paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
                 assertThat(paragraph.getLineRight(0), equalTo(layoutWidth))
             }
@@ -1936,15 +2006,15 @@
             val fontSizeInPx = fontSize.toPx().value
 
             texts.map { text ->
+                val layoutWidth = (text.length + 2) * fontSizeInPx
                 val paragraph = simpleParagraph(
                     text = text,
                     textAlign = TextAlign.Center,
-                    fontSize = fontSize
+                    fontSize = fontSize,
+                    constraints = ParagraphConstraints(width = layoutWidth)
                 )
-                val layoutWidth = (text.length + 2) * fontSizeInPx
-                paragraph.layout(ParagraphConstraints(width = layoutWidth))
-                val textWidth = text.length * fontSizeInPx
 
+                val textWidth = text.length * fontSizeInPx
                 assertThat(
                     paragraph.getLineLeft(0),
                     equalTo(layoutWidth / 2 - textWidth / 2)
@@ -1968,9 +2038,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textAlign = TextAlign.Start,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineLeft(0), equalTo(0.0f))
         }
@@ -1987,9 +2057,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textAlign = TextAlign.End,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineRight(0), equalTo(layoutWidth))
         }
@@ -2006,9 +2076,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textAlign = TextAlign.Start,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineRight(0), equalTo(layoutWidth))
         }
@@ -2025,9 +2095,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textAlign = TextAlign.End,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineLeft(0), equalTo(0.0f))
         }
@@ -2047,9 +2117,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textAlign = TextAlign.Justify,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.getLineLeft(0), equalTo(0.0f))
             assertThat(paragraph.getLineRight(0), equalTo(layoutWidth))
@@ -2069,9 +2139,10 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textDirectionAlgorithm = TextDirectionAlgorithm.ForceLtr,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
+
             // The position of the last character in display order.
             val position = PxPosition(("a.".length * fontSizeInPx + 1).px, (fontSizeInPx / 2).px)
             val charIndex = paragraph.getOffsetForPosition(position)
@@ -2090,9 +2161,10 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textDirectionAlgorithm = TextDirectionAlgorithm.ForceRtl,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
+
             // The position of the first character in display order.
             val position = PxPosition((fontSizeInPx / 2 + 1).px, (fontSizeInPx / 2).px)
             val charIndex = paragraph.getOffsetForPosition(position)
@@ -2110,9 +2182,10 @@
 
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
+
             for (i in 0..text.length) {
                 // The position of the i-th character in display order.
                 val position = PxPosition((i * fontSizeInPx + 1).px, (fontSizeInPx / 2).px)
@@ -2132,10 +2205,11 @@
 
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
-            for (i in 0 until text.length) {
+
+            for (i in text.indices) {
                 // The position of the i-th character in display order.
                 val position = PxPosition((i * fontSizeInPx + 1).px, (fontSizeInPx / 2).px)
                 val charIndex = paragraph.getOffsetForPosition(position)
@@ -2154,9 +2228,10 @@
 
             val paragraph = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
+
             // The first character in display order should be '.'
             val position = PxPosition((fontSizeInPx / 2 + 1).px, (fontSizeInPx / 2).px)
             val index = paragraph.getOffsetForPosition(position)
@@ -2177,9 +2252,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                lineHeight = lineHeight
+                lineHeight = lineHeight,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             assertThat(paragraph.lineCount, equalTo(4))
             // TODO(Migration/haoyuchang): Due to bug b/120530738, the height of the first line is
@@ -2209,9 +2284,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontSize = fontSize,
-                lineHeight = lineHeight
+                lineHeight = lineHeight,
+                constraints = ParagraphConstraints(width = layoutWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = layoutWidth))
 
             val lastLine = paragraph.lineCount - 1
             // In the sample_font.ttf, the height of the line should be
@@ -2231,9 +2306,9 @@
 
             val paragraph = simpleParagraph(
                 text = text,
-                textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+                textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             // Make sure there is only one line, so that we can use getLineRight to test fontSize.
             assertThat(paragraph.lineCount, equalTo(1))
@@ -2256,9 +2331,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             // Make sure there is only one line, so that we can use getLineRight to test fontSize.
             assertThat(paragraph.lineCount, equalTo(1))
@@ -2287,9 +2362,9 @@
                 textStyles = listOf(
                     AnnotatedString.Item(textStyle, 0, text.length),
                     AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
-                )
+                ),
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             // Make sure there is only one line, so that we can use getLineRight to test fontSize.
             assertThat(paragraph.lineCount, equalTo(1))
@@ -2311,9 +2386,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             assertThat(
                 paragraph.getLineRight(0),
@@ -2340,9 +2415,9 @@
                     AnnotatedString.Item(textStyle, 0, text.length),
                     AnnotatedString.Item(textStyleNested, 0, text.length)
                 ),
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             assertThat(
                 paragraph.getLineRight(0),
@@ -2370,9 +2445,9 @@
                     AnnotatedString.Item(fontSizeStyle, 0, text.length),
                     AnnotatedString.Item(fontSizeScaleStyle, 0, text.length)
                 ),
-                fontSize = paragraphFontSize
+                fontSize = paragraphFontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             assertThat(
                 paragraph.getLineRight(0),
@@ -2400,9 +2475,9 @@
                     AnnotatedString.Item(fontSizeScaleStyle, 0, text.length),
                     AnnotatedString.Item(fontSizeStyle, 0, text.length)
                 ),
-                fontSize = paragraphFontSize
+                fontSize = paragraphFontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             assertThat(
                 paragraph.getLineRight(0),
@@ -2434,9 +2509,9 @@
                     AnnotatedString.Item(fontSizeStyle, 0, text.length),
                     AnnotatedString.Item(fontSizeScaleStyle2, 0, text.length)
                 ),
-                fontSize = paragraphFontSize
+                fontSize = paragraphFontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             assertThat(
                 paragraph.getLineRight(0),
@@ -2458,9 +2533,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             // Make sure there is only one line, so that we can use getLineRight to test fontSize.
             assertThat(paragraph.lineCount, equalTo(1))
@@ -2485,9 +2560,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             // Make sure there is only one line, so that we can use getLineRight to test fontSize.
             assertThat(paragraph.lineCount, equalTo(1))
@@ -2517,9 +2592,9 @@
                     AnnotatedString.Item(textStyle, 0, text.length),
                     AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
                 ),
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             // Make sure there is only one line, so that we can use getLineRight to test fontSize.
             assertThat(paragraph.lineCount, equalTo(1))
@@ -2542,9 +2617,9 @@
                 text = text,
                 textIndent = TextIndent(firstLine = indent.px),
                 fontSize = fontSize,
-                fontFamily = fontFamilyMeasureFont
+                fontFamily = fontFamilyMeasureFont,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             // This position should point to the first character 'a' if indent is applied.
             // Otherwise this position will point to the second character 'b'.
@@ -2567,9 +2642,9 @@
                 text = text,
                 textIndent = TextIndent(firstLine = indent.px),
                 fontSize = fontSize,
-                fontFamily = fontFamilyMeasureFont
+                fontFamily = fontFamilyMeasureFont,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             assertThat(paragraph.lineCount, equalTo(2))
             // This position should point to the first character of the first line if indent is
@@ -2596,9 +2671,9 @@
                     restLine = indent.px
                 ),
                 fontSize = fontSize,
-                fontFamily = fontFamilyMeasureFont
+                fontFamily = fontFamilyMeasureFont,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             // This position should point to the first character of the second line if indent is
             // applied. Otherwise this position will point to the second character of the second line.
@@ -2630,9 +2705,9 @@
                     AnnotatedString.Item(textStyle, "a".length, text.length)
                 ),
                 fontSize = fontSize,
-                fontFamily = fontFamilyCustom100
+                fontFamily = fontFamilyCustom100,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             assertThat(paragraph.lineCount, equalTo(1))
             assertThat(paragraph.getLineWidth(0), equalTo(expectedWidth))
@@ -2654,9 +2729,9 @@
                     AnnotatedString.Item(textStyle, 0, "aA".length)
                 ),
                 fontSize = fontSize,
-                fontFamily = fontFamilyKernFont
+                fontFamily = fontFamilyKernFont,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             // Two characters are kerning, so minus 0.4 * fontSize
             val expectedWidth = text.length * fontSizeInPx - 0.4f * fontSizeInPx
@@ -2685,12 +2760,14 @@
                 text = text,
                 textStyles = listOf(
                     AnnotatedString.Item(textStyle, 0, text.length)
-                )
+                ),
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraphShadow.layout(ParagraphConstraints(width = paragraphWidth))
 
-            val paragraph = simpleParagraph(text = text)
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
+            val paragraph = simpleParagraph(
+                text = text,
+                constraints = ParagraphConstraints(width = paragraphWidth)
+            )
 
             assertThat(paragraphShadow.bitmap(), not(equalToBitmap(paragraph.bitmap())))
         }
@@ -2708,16 +2785,16 @@
 
             val paragraphWithoutColor = simpleParagraph(
                 text = text,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(paragraphWidth)
             )
-            paragraphWithoutColor.layout(ParagraphConstraints(paragraphWidth))
 
             val paragraphWithColor = simpleParagraph(
                 text = text,
                 textStyle = textStyle,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(paragraphWidth)
             )
-            paragraphWithColor.layout(ParagraphConstraints(paragraphWidth))
 
             assertThat(
                 paragraphWithColor.bitmap(),
@@ -2739,9 +2816,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 textStyle = textStyle,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(Float.MAX_VALUE))
 
             assertThat(
                 paragraph.getLineRight(0),
@@ -2759,9 +2836,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -2792,9 +2869,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val firstLineLeft = paragraph.getLineLeft(0)
@@ -2839,9 +2916,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -2878,9 +2955,9 @@
         val paragraph = simpleParagraph(
             text = text,
             fontFamily = fontFamilyMeasureFont,
-            fontSize = 20.sp
+            fontSize = 20.sp,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val actualPath = paragraph.getPathForRange(1, 1)
 
@@ -2893,9 +2970,9 @@
         val paragraph = simpleParagraph(
             text = text,
             fontFamily = fontFamilyMeasureFont,
-            fontSize = 20.sp
+            fontSize = 20.sp,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val actualPath = paragraph.getPathForRange(0, 0)
 
@@ -2911,9 +2988,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineRight = paragraph.getLineRight(0)
@@ -2936,9 +3013,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineRight = paragraph.getLineRight(0)
@@ -2961,9 +3038,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineRight = paragraph.getLineRight(0)
@@ -2986,9 +3063,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -3019,9 +3096,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -3045,9 +3122,9 @@
             val paragraph = simpleParagraph(
                 text = text,
                 fontFamily = fontFamilyMeasureFont,
-                fontSize = fontSize
+                fontSize = fontSize,
+                constraints = ParagraphConstraints(width = Float.MAX_VALUE)
             )
-            paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
             val expectedPath = Path()
             val lineLeft = paragraph.getLineLeft(0)
@@ -3068,9 +3145,9 @@
         val paragraph = simpleParagraph(
             text = text,
             fontFamily = fontFamilyMeasureFont,
-            fontSize = 20.sp
+            fontSize = 20.sp,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val result = paragraph.getWordBoundary(text.indexOf('a'))
 
@@ -3084,9 +3161,9 @@
         val paragraph = simpleParagraph(
             text = text,
             fontFamily = fontFamilyMeasureFont,
-            fontSize = 20.sp
+            fontSize = 20.sp,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val resultEnglish = paragraph.getWordBoundary(text.indexOf('a'))
         val resultHebrew = paragraph.getWordBoundary(text.indexOf('\u05d1'))
@@ -3106,16 +3183,16 @@
         val paragraph = simpleParagraph(
             text = text,
             textStyle = TextStyle(fontSize = fontSize),
-            density = Density(density = 1f, fontScale = 1f)
+            density = Density(density = 1f, fontScale = 1f),
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         val doubleFontSizeParagraph = simpleParagraph(
             text = text,
             textStyle = TextStyle(fontSize = fontSize),
-            density = Density(density = 1f, fontScale = densityMultiplier)
+            density = Density(density = 1f, fontScale = densityMultiplier),
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        doubleFontSizeParagraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         assertThat(
             doubleFontSizeParagraph.maxIntrinsicWidth,
@@ -3124,33 +3201,16 @@
         assertThat(doubleFontSizeParagraph.height, equalTo(paragraph.height * densityMultiplier))
     }
 
-    @Test(expected = IllegalStateException::class)
-    fun width_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleParagraph()
-
-        paragraph.width
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun height_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleParagraph()
-
-        paragraph.height
-    }
-
-    @Test
-    fun minIntrinsicWidth_default_value() {
-        val paragraph = simpleParagraph()
-
-        assertThat(paragraph.minIntrinsicWidth, equalTo(0.0f))
-    }
-
     @Test
     fun minInstrinsicWidth_includes_white_space() {
         withDensity(defaultDensity) {
             val fontSize = 12.sp
             val text = "b "
-            val paragraph = simpleParagraph(text = text, textStyle = TextStyle(fontSize = fontSize))
+            val paragraph = simpleParagraph(
+                text = text,
+                textStyle = TextStyle(fontSize = fontSize),
+                constraints = ParagraphConstraints(Float.MAX_VALUE)
+            )
 
             val expectedWidth = text.length * fontSize.toPx().value
             assertThat(paragraph.minIntrinsicWidth, equalTo(expectedWidth))
@@ -3166,7 +3226,11 @@
                 string + "a".repeat(next) + " "
             }
             val fontSize = 12.sp
-            val paragraph = simpleParagraph(text = text, textStyle = TextStyle(fontSize = fontSize))
+            val paragraph = simpleParagraph(
+                text = text,
+                textStyle = TextStyle(fontSize = fontSize),
+                constraints = ParagraphConstraints(Float.MAX_VALUE)
+            )
 
             // +1 is for the white space
             val expectedWidth = (maxWordLength + 1) * fontSize.toPx().value
@@ -3187,7 +3251,8 @@
                     AnnotatedString.Item(
                         TextStyle(fontSize = styledFontSize), "a".length, "a bb ".length
                     )
-                )
+                ),
+                constraints = ParagraphConstraints(Float.MAX_VALUE)
             )
 
             val expectedWidth = "bb ".length * styledFontSize.toPx().value
@@ -3195,54 +3260,15 @@
         }
     }
 
-    @Test
-    fun maxIntrinsicWidth_default_value() {
-        val paragraph = simpleParagraph()
-
-        assertThat(paragraph.maxIntrinsicWidth, equalTo(0.0f))
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun firstBaseline_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleParagraph()
-
-        paragraph.firstBaseline
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun lastBaseline_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleParagraph()
-
-        paragraph.lastBaseline
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun didExceedMaxLines_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleParagraph()
-
-        paragraph.didExceedMaxLines
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun paint_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleParagraph()
-
-        paragraph.paint(mock(Canvas::class.java))
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun getOffsetForPosition_throws_exception_if_layout_is_not_called() {
-        val paragraph = simpleParagraph()
-
-        paragraph.getOffsetForPosition(PxPosition.Origin)
-    }
-
     @Test(expected = AssertionError::class)
     fun getPathForRange_throws_exception_if_start_larger_than_end() {
         val text = "ab"
         val textStart = 0
         val textEnd = text.length
-        val paragraph = simpleParagraph(text = text)
+        val paragraph = simpleParagraph(
+            text = text,
+            constraints = ParagraphConstraints(Float.MAX_VALUE)
+        )
 
         paragraph.getPathForRange(textEnd, textStart)
     }
@@ -3252,7 +3278,10 @@
         val text = "ab"
         val textStart = 0
         val textEnd = text.length
-        val paragraph = simpleParagraph(text = text)
+        val paragraph = simpleParagraph(
+            text = text,
+            constraints = ParagraphConstraints(Float.MAX_VALUE)
+        )
 
         paragraph.getPathForRange(textStart - 2, textEnd - 1)
     }
@@ -3262,7 +3291,10 @@
         val text = "ab"
         val textStart = 0
         val textEnd = text.length
-        val paragraph = simpleParagraph(text = text)
+        val paragraph = simpleParagraph(
+            text = text,
+            constraints = ParagraphConstraints(Float.MAX_VALUE)
+        )
 
         paragraph.getPathForRange(textStart, textEnd + 1)
     }
@@ -3287,9 +3319,10 @@
                 resourceLoader = TestFontResourceLoader(context)
             )
 
-            val paragraph = Paragraph(paragraphIntrinsics = paragraphIntrinsics)
-
-            paragraph.layout(ParagraphConstraints(fontSizeInPx * text.length))
+            val paragraph = Paragraph(
+                paragraphIntrinsics = paragraphIntrinsics,
+                constraints = ParagraphConstraints(fontSizeInPx * text.length)
+            )
 
             assertThat(paragraph.maxIntrinsicWidth, equalTo(paragraphIntrinsics.maxIntrinsicWidth))
             assertThat(paragraph.width, equalTo(fontSizeInPx * text.length))
@@ -3309,7 +3342,8 @@
         textStyle: TextStyle? = null,
         density: Density? = null,
         textDirectionAlgorithm: TextDirectionAlgorithm? = null,
-        layoutDirection: LayoutDirection = LayoutDirection.Ltr
+        layoutDirection: LayoutDirection = LayoutDirection.Ltr,
+        constraints: ParagraphConstraints
     ): Paragraph {
         return Paragraph(
             text = text,
@@ -3326,6 +3360,7 @@
                 lineHeight = lineHeight
             ),
             maxLines = maxLines,
+            constraints = constraints,
             density = density ?: defaultDensity,
             layoutDirection = layoutDirection,
             resourceLoader = TestFontResourceLoader(context)
diff --git a/ui/ui-text/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt b/ui/ui-text/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
index 072ce79..2645a7c 100644
--- a/ui/ui-text/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
+++ b/ui/ui-text/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
@@ -94,12 +94,11 @@
                     textStyle = TextStyle(
                         fontSize = fontSize,
                         fontFamily = fontFamily
-                    )
+                    ),
+                    // 2 chars width
+                    constraints = ParagraphConstraints(width = 2 * fontSize.toPx().value)
                 )
 
-                // 2 chars width
-                paragraphAndroid.layout(ParagraphConstraints(width = 2 * fontSize.toPx().value))
-
                 val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
                 textPaint.textSize = fontSize.toPx().value
                 textPaint.typeface = TypefaceAdapter().create(fontFamily)
@@ -123,9 +122,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(ForegroundColorSpan::class, 0, text.length))
     }
@@ -137,9 +136,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(ForegroundColorSpan::class, 0, "abc".length))
     }
@@ -155,9 +154,9 @@
             textStyles = listOf(
                 AnnotatedString.Item(textStyle, 0, text.length),
                 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(ForegroundColorSpan::class, 0, text.length))
         assertThat(paragraph.charSequence, hasSpan(ForegroundColorSpan::class, 0, "abc".length))
@@ -174,9 +173,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence, hasSpan(StrikethroughSpan::class, 0, text.length))
@@ -189,9 +188,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence, hasSpan(UnderlineSpan::class, 0, text.length))
@@ -204,9 +203,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence, hasSpan(StrikethroughSpan::class, 0, "abc".length))
@@ -219,9 +218,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence, hasSpan(UnderlineSpan::class, 0, "abc".length))
@@ -238,9 +237,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence, hasSpan(UnderlineSpan::class, 0, "abc".length))
@@ -257,9 +256,9 @@
 
             val paragraph = simpleParagraph(
                 text = text,
-                textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+                textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             assertThat(paragraph.charSequence, hasSpan(AbsoluteSizeSpan::class, 0, text.length))
         }
@@ -275,9 +274,9 @@
 
             val paragraph = simpleParagraph(
                 text = text,
-                textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+                textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             assertThat(paragraph.charSequence, hasSpan(AbsoluteSizeSpan::class, 0, "abc".length))
         }
@@ -298,9 +297,9 @@
                 textStyles = listOf(
                     AnnotatedString.Item(textStyle, 0, text.length),
                     AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
-                )
+                ),
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             assertThat(paragraph.charSequence, hasSpan(AbsoluteSizeSpan::class, 0, text.length))
             assertThat(paragraph.charSequence, hasSpan(AbsoluteSizeSpan::class, 0, "abc".length))
@@ -319,9 +318,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -339,9 +338,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -359,9 +358,10 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
+
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence, hasSpan(LetterSpacingSpan::class, 0, text.length))
     }
@@ -373,9 +373,10 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
+
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence, hasSpan(LetterSpacingSpan::class, 0, "abc".length))
     }
@@ -391,9 +392,10 @@
             textStyles = listOf(
                 AnnotatedString.Item(textStyle, 0, text.length),
                 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
+
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence, hasSpan(LetterSpacingSpan::class, 0, text.length))
         assertThat(paragraph.charSequence, hasSpan(LetterSpacingSpan::class, 0, "abc".length))
@@ -411,9 +413,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence,
@@ -431,9 +433,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence,
@@ -456,9 +458,9 @@
             textStyles = listOf(
                 AnnotatedString.Item(textStyle, 0, text.length),
                 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(paragraph.charSequence,
@@ -487,9 +489,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(LocaleSpan::class, 0, text.length))
     }
@@ -502,9 +504,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(LocaleSpan::class, 0, "abc".length))
     }
@@ -520,9 +522,9 @@
             textStyles = listOf(
                 AnnotatedString.Item(textStyle, 0, text.length),
                 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(LocaleSpan::class, 0, text.length))
         assertThat(paragraph.charSequence, hasSpan(LocaleSpan::class, 0, "abc".length))
@@ -539,10 +541,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(BaselineShiftSpan::class, 0, text.length))
     }
@@ -554,10 +555,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(BaselineShiftSpan::class, 0, "abc".length))
     }
@@ -574,10 +574,9 @@
             textStyles = listOf(
                 AnnotatedString.Item(textStyle, 0, text.length),
                 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, hasSpan(BaselineShiftSpan::class, 0, text.length))
         assertThat(paragraph.charSequence, hasSpan(BaselineShiftSpan::class, 0, "abc".length))
@@ -599,10 +598,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence, not(hasSpan(ScaleXSpan::class, 0, text.length)))
         assertThat(paragraph.charSequence, not(hasSpan(SkewXSpan::class, 0, text.length)))
@@ -621,10 +619,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -646,10 +643,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -666,10 +662,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textIndent = TextIndent(firstLine.px, restLine.px)
+            textIndent = TextIndent(firstLine.px, restLine.px),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -691,10 +686,9 @@
             text = text,
             textStyles = listOf(
                 AnnotatedString.Item(textStyle, start = 0, end = text.length)
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -727,10 +721,9 @@
             textStyles = listOf(
                 AnnotatedString.Item(textStyle, start = 0, end = text.length),
                 AnnotatedString.Item(textStyleOverwrite, start = 0, end = "abc".length)
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -776,9 +769,9 @@
                     expectedStart,
                     expectedEnd
                 )
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(
@@ -814,9 +807,9 @@
                     expectedStart,
                     expectedEnd
                 )
-            )
+            ),
+            constraints = ParagraphConstraints(width = 100.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(paragraph.charSequence.toString(), equalTo(text))
         assertThat(
@@ -834,10 +827,9 @@
 
         val paragraph = simpleParagraph(
             text = text,
-            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length))
+            textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
+            constraints = ParagraphConstraints(width = 100.0f) // width is not important
         )
-        // width is not important
-        paragraph.layout(ParagraphConstraints(width = 100.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -851,9 +843,9 @@
         val typefaceAdapter = mock<TypefaceAdapter>()
         val paragraph = simpleParagraph(
             text = "abc",
-            typefaceAdapter = typefaceAdapter
+            typefaceAdapter = typefaceAdapter,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         verify(typefaceAdapter, never()).create(
             fontFamily = any(),
@@ -874,9 +866,9 @@
                 fontFamily = null,
                 fontWeight = FontWeight.bold
             ),
-            typefaceAdapter = typefaceAdapter
+            typefaceAdapter = typefaceAdapter,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         verify(typefaceAdapter, times(1)).create(
             fontFamily = eq(null),
@@ -900,9 +892,9 @@
                 fontFamily = null,
                 fontStyle = FontStyle.Italic
             ),
-            typefaceAdapter = typefaceAdapter
+            typefaceAdapter = typefaceAdapter,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         verify(typefaceAdapter, times(1)).create(
             fontFamily = eq(null),
@@ -927,9 +919,9 @@
             textStyle = TextStyle(
                 fontFamily = fontFamily
             ),
-            typefaceAdapter = typefaceAdapter
+            typefaceAdapter = typefaceAdapter,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         verify(typefaceAdapter, times(1)).create(
             fontFamily = eq(fontFamily),
@@ -952,9 +944,9 @@
             textStyle = TextStyle(
                 fontFamily = fontFamily
             ),
-            typefaceAdapter = typefaceAdapter
+            typefaceAdapter = typefaceAdapter,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
 
         verify(typefaceAdapter, times(1)).create(
             fontFamily = eq(fontFamily),
@@ -979,9 +971,10 @@
                     fontFamily = fontFamily,
                     fontSize = fontSize
                 ),
-                ellipsis = true
+                ellipsis = true,
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
+
             for (i in 0 until paragraph.lineCount) {
                 assertFalse(paragraph.isEllipsisApplied(i))
             }
@@ -1002,9 +995,9 @@
                 textStyle = TextStyle(
                     fontFamily = fontFamily,
                     fontSize = fontSize
-                )
+                ),
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             assertTrue(paragraph.isEllipsisApplied(0))
         }
@@ -1024,9 +1017,9 @@
                 textStyle = TextStyle(
                     fontFamily = fontFamily,
                     fontSize = fontSize
-                )
+                ),
+                constraints = ParagraphConstraints(width = paragraphWidth)
             )
-            paragraph.layout(ParagraphConstraints(width = paragraphWidth))
 
             for (i in 0 until paragraph.lineCount) {
                 assertFalse(paragraph.isEllipsisApplied(i))
@@ -1040,9 +1033,9 @@
             val fontSize = 100.sp
             val paragraph = simpleParagraph(
                 text = "",
-                textStyle = TextStyle(fontSize = fontSize)
+                textStyle = TextStyle(fontSize = fontSize),
+                constraints = ParagraphConstraints(width = 0.0f)
             )
-            paragraph.layout(ParagraphConstraints(width = 0.0f))
 
             assertThat(paragraph.textPaint.textSize, equalTo(fontSize.toPx().value))
         }
@@ -1058,9 +1051,9 @@
                 textStyle = TextStyle(
                     fontSize = fontSize,
                     fontSizeScale = fontSizeScale
-                )
+                ),
+                constraints = ParagraphConstraints(width = 0.0f)
             )
-            paragraph.layout(ParagraphConstraints(width = 0.0f))
 
             assertThat(paragraph.textPaint.textSize, equalTo(fontSize.toPx().value * fontSizeScale))
         }
@@ -1073,9 +1066,9 @@
 
         val paragraph = simpleParagraph(
             text = "",
-            textStyle = TextStyle(localeList = localeList)
+            textStyle = TextStyle(localeList = localeList),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.textPaint.textLocale.language, equalTo(platformLocale.language))
         assertThat(paragraph.textPaint.textLocale.country, equalTo(platformLocale.country))
@@ -1086,9 +1079,9 @@
         val color = Color(0x12345678)
         val paragraph = simpleParagraph(
             text = "",
-            textStyle = TextStyle(color = color)
+            textStyle = TextStyle(color = color),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.textPaint.color, equalTo(color.toArgb()))
     }
@@ -1098,9 +1091,9 @@
         val letterSpacing = 2.0f
         val paragraph = simpleParagraph(
             text = "",
-            textStyle = TextStyle(letterSpacing = letterSpacing)
+            textStyle = TextStyle(letterSpacing = letterSpacing),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.textPaint.letterSpacing, equalTo(letterSpacing))
     }
@@ -1110,9 +1103,9 @@
         val fontFeatureSettings = "\"kern\" 0"
         val paragraph = simpleParagraph(
             text = "",
-            textStyle = TextStyle(fontFeatureSettings = fontFeatureSettings)
+            textStyle = TextStyle(fontFeatureSettings = fontFeatureSettings),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.textPaint.fontFeatureSettings, equalTo(fontFeatureSettings))
     }
@@ -1126,9 +1119,9 @@
                 textGeometricTransform = TextGeometricTransform(
                     scaleX = scaleX
                 )
-            )
+            ),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.textPaint.textScaleX, equalTo(scaleX))
     }
@@ -1142,9 +1135,9 @@
                 textGeometricTransform = TextGeometricTransform(
                     skewX = skewX
                 )
-            )
+            ),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.textPaint.textSkewX, equalTo(skewX))
     }
@@ -1153,9 +1146,9 @@
     fun testTextStyle_decoration_underline_appliedOnTextPaint() {
         val paragraph = simpleParagraph(
             text = "",
-            textStyle = TextStyle(decoration = TextDecoration.Underline)
+            textStyle = TextStyle(decoration = TextDecoration.Underline),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.textPaint.isUnderlineText, equalTo(true))
     }
@@ -1164,9 +1157,9 @@
     fun testTextStyle_decoration_lineThrough_appliedOnTextPaint() {
         val paragraph = simpleParagraph(
             text = "",
-            textStyle = TextStyle(decoration = TextDecoration.LineThrough)
+            textStyle = TextStyle(decoration = TextDecoration.LineThrough),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.textPaint.isStrikeThruText, equalTo(true))
     }
@@ -1179,9 +1172,9 @@
         val color = Color(0x12345678)
         val paragraph = simpleParagraph(
             text = text,
-            textStyle = TextStyle(background = color)
+            textStyle = TextStyle(background = color),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(paragraph.charSequence,
             hasSpan(BackgroundColorSpan::class, 0, text.length) { span ->
@@ -1198,9 +1191,9 @@
         val baselineShift = BaselineShift.Subscript
         val paragraph = simpleParagraph(
             text = text,
-            textStyle = TextStyle(baselineShift = baselineShift)
+            textStyle = TextStyle(baselineShift = baselineShift),
+            constraints = ParagraphConstraints(width = 0.0f)
         )
-        paragraph.layout(ParagraphConstraints(width = 0.0f))
 
         assertThat(
             paragraph.charSequence,
@@ -1213,9 +1206,10 @@
     @Test
     fun locale_isDefaultLocaleIfNotProvided() {
         val text = "abc"
-        val paragraph = simpleParagraph(text = text)
-
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
+        val paragraph = simpleParagraph(
+            text = text,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
 
         assertThat(
             paragraph.textLocale.toLanguageTag(),
@@ -1229,11 +1223,10 @@
         val text = "abc"
         val paragraph = simpleParagraph(
             text = text,
-            textStyle = TextStyle(localeList = localeList)
+            textStyle = TextStyle(localeList = localeList),
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
-
         assertThat(paragraph.textLocale.toLanguageTag(), equalTo("en-US"))
     }
 
@@ -1243,11 +1236,10 @@
         val text = "abc"
         val paragraph = simpleParagraph(
             text = text,
-            textStyle = TextStyle(localeList = localeList)
+            textStyle = TextStyle(localeList = localeList),
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
-
         assertThat(paragraph.textLocale.toLanguageTag(), equalTo("ja-JP"))
     }
 
@@ -1257,11 +1249,10 @@
         val text = "abc"
         val paragraph = simpleParagraph(
             text = text,
-            textStyle = TextStyle(localeList = localeList)
+            textStyle = TextStyle(localeList = localeList),
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
 
-        paragraph.layout(ParagraphConstraints(width = Float.MAX_VALUE))
-
         assertThat(paragraph.textLocale.toLanguageTag(), equalTo("ja"))
     }
 
@@ -1357,8 +1348,11 @@
     @Test
     fun floatingWidth() {
         val floatWidth = 1.3f
-        val paragraph = simpleParagraph(text = "Hello, World")
-        paragraph.layout(ParagraphConstraints(floatWidth))
+        val paragraph = simpleParagraph(
+            text = "Hello, World",
+            constraints = ParagraphConstraints(floatWidth)
+        )
+
         assertEquals(floatWidth, paragraph.width)
     }
 
@@ -1369,6 +1363,7 @@
         textAlign: TextAlign? = null,
         ellipsis: Boolean? = null,
         maxLines: Int? = null,
+        constraints: ParagraphConstraints,
         textStyle: TextStyle? = null,
         layoutDirection: LayoutDirection = LayoutDirection.Ltr,
         typefaceAdapter: TypefaceAdapter = TypefaceAdapter()
@@ -1384,6 +1379,7 @@
             ),
             maxLines = maxLines,
             ellipsis = ellipsis,
+            constraints = constraints,
             density = Density(density = 1f),
             layoutDirection = layoutDirection
         )