diff --git a/settings.gradle b/settings.gradle
index 7bfddaf..8a5bac9 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1048,6 +1048,7 @@
 includeProject(":test:uiautomator:uiautomator-lint", [BuildType.MAIN])
 includeProject(":test:uiautomator:integration-tests:testapp", [BuildType.MAIN])
 includeProject(":text:text-vertical", [BuildType.MAIN])
+includeProject(":text:text-vertical-testapp", "text/text-vertical/testapp", [BuildType.MAIN])
 includeProject(":tracing:tracing")
 includeProject(":tracing:tracing-benchmark", "tracing/benchmark", [BuildType.MAIN, BuildType.COMPOSE])
 includeProject(":tracing:tracing-ktx")
diff --git a/text/text-vertical/api/current.txt b/text/text-vertical/api/current.txt
index e6f50d0..caed866 100644
--- a/text/text-vertical/api/current.txt
+++ b/text/text-vertical/api/current.txt
@@ -1 +1,70 @@
 // Signature format: 4.0
+package androidx.text.vertical {
+
+  public final class RubySpan {
+    method public int getOrientation();
+    method public CharSequence getText();
+    method public float getTextScale();
+    property public int orientation;
+    property public CharSequence text;
+    property public float textScale;
+  }
+
+  public static final class RubySpan.Builder {
+    ctor public RubySpan.Builder(CharSequence text);
+    method public androidx.text.vertical.RubySpan build();
+    method public androidx.text.vertical.RubySpan.Builder setOrientation(int orientation);
+    method public androidx.text.vertical.RubySpan.Builder setTextScale(float textScale);
+  }
+
+  public final class TextOrientation {
+    property public static int MIXED;
+    property public static int SIDEWAYS;
+    property public static int UPRIGHT;
+    field public static final androidx.text.vertical.TextOrientation INSTANCE;
+    field public static final int MIXED = 0; // 0x0
+    field public static final int SIDEWAYS = 2; // 0x2
+    field public static final int UPRIGHT = 1; // 0x1
+  }
+
+  public sealed interface TextOrientationSpan {
+  }
+
+  public static final class TextOrientationSpan.Sideways implements androidx.text.vertical.TextOrientationSpan {
+    ctor public TextOrientationSpan.Sideways();
+  }
+
+  public static final class TextOrientationSpan.TextCombineUpright implements androidx.text.vertical.TextOrientationSpan {
+    ctor public TextOrientationSpan.TextCombineUpright();
+  }
+
+  public static final class TextOrientationSpan.Upright implements androidx.text.vertical.TextOrientationSpan {
+    ctor public TextOrientationSpan.Upright();
+  }
+
+  public final class VerticalTextLayout {
+    method public void draw(android.graphics.Canvas canvas, @Px float x, @Px float y);
+    method public int getEnd();
+    method public float getHeight();
+    method public int getOrientation();
+    method public android.text.TextPaint getPaint();
+    method public int getStart();
+    method public CharSequence getText();
+    method @Px public float getWidth();
+    property public int end;
+    property @Px public float height;
+    property public int orientation;
+    property public android.text.TextPaint paint;
+    property public int start;
+    property public CharSequence text;
+    property @Px public float width;
+  }
+
+  public static final class VerticalTextLayout.Builder {
+    ctor public VerticalTextLayout.Builder(CharSequence text, int start, int end, android.text.TextPaint paint, @Px float height);
+    method public androidx.text.vertical.VerticalTextLayout build();
+    method public androidx.text.vertical.VerticalTextLayout.Builder setOrientation(int orientation);
+  }
+
+}
+
diff --git a/text/text-vertical/api/restricted_current.txt b/text/text-vertical/api/restricted_current.txt
index e6f50d0..caed866 100644
--- a/text/text-vertical/api/restricted_current.txt
+++ b/text/text-vertical/api/restricted_current.txt
@@ -1 +1,70 @@
 // Signature format: 4.0
+package androidx.text.vertical {
+
+  public final class RubySpan {
+    method public int getOrientation();
+    method public CharSequence getText();
+    method public float getTextScale();
+    property public int orientation;
+    property public CharSequence text;
+    property public float textScale;
+  }
+
+  public static final class RubySpan.Builder {
+    ctor public RubySpan.Builder(CharSequence text);
+    method public androidx.text.vertical.RubySpan build();
+    method public androidx.text.vertical.RubySpan.Builder setOrientation(int orientation);
+    method public androidx.text.vertical.RubySpan.Builder setTextScale(float textScale);
+  }
+
+  public final class TextOrientation {
+    property public static int MIXED;
+    property public static int SIDEWAYS;
+    property public static int UPRIGHT;
+    field public static final androidx.text.vertical.TextOrientation INSTANCE;
+    field public static final int MIXED = 0; // 0x0
+    field public static final int SIDEWAYS = 2; // 0x2
+    field public static final int UPRIGHT = 1; // 0x1
+  }
+
+  public sealed interface TextOrientationSpan {
+  }
+
+  public static final class TextOrientationSpan.Sideways implements androidx.text.vertical.TextOrientationSpan {
+    ctor public TextOrientationSpan.Sideways();
+  }
+
+  public static final class TextOrientationSpan.TextCombineUpright implements androidx.text.vertical.TextOrientationSpan {
+    ctor public TextOrientationSpan.TextCombineUpright();
+  }
+
+  public static final class TextOrientationSpan.Upright implements androidx.text.vertical.TextOrientationSpan {
+    ctor public TextOrientationSpan.Upright();
+  }
+
+  public final class VerticalTextLayout {
+    method public void draw(android.graphics.Canvas canvas, @Px float x, @Px float y);
+    method public int getEnd();
+    method public float getHeight();
+    method public int getOrientation();
+    method public android.text.TextPaint getPaint();
+    method public int getStart();
+    method public CharSequence getText();
+    method @Px public float getWidth();
+    property public int end;
+    property @Px public float height;
+    property public int orientation;
+    property public android.text.TextPaint paint;
+    property public int start;
+    property public CharSequence text;
+    property @Px public float width;
+  }
+
+  public static final class VerticalTextLayout.Builder {
+    ctor public VerticalTextLayout.Builder(CharSequence text, int start, int end, android.text.TextPaint paint, @Px float height);
+    method public androidx.text.vertical.VerticalTextLayout build();
+    method public androidx.text.vertical.VerticalTextLayout.Builder setOrientation(int orientation);
+  }
+
+}
+
diff --git a/text/text-vertical/build.gradle b/text/text-vertical/build.gradle
index f4e4ebe..6cfa0aa 100644
--- a/text/text-vertical/build.gradle
+++ b/text/text-vertical/build.gradle
@@ -31,11 +31,22 @@
 
 dependencies {
     api(libs.kotlinStdlib)
-    // Add dependencies here
+    api("androidx.annotation:annotation:1.8.1")
+
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testRules)
+    androidTestImplementation(libs.testRunner)
+    androidTestImplementation(libs.truth)
 }
 
 android {
     namespace = "androidx.text.vertical"
+
+    defaultConfig {
+        minSdk = 36
+    }
+    compileSdk = 36
 }
 
 androidx {
diff --git a/text/text-vertical/src/androidTest/java/androidx/text/vertical/LayoutRunTest.kt b/text/text-vertical/src/androidTest/java/androidx/text/vertical/LayoutRunTest.kt
new file mode 100644
index 0000000..56109bf
--- /dev/null
+++ b/text/text-vertical/src/androidTest/java/androidx/text/vertical/LayoutRunTest.kt
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.Paint.FontMetricsInt
+import android.text.TextPaint
+import androidx.text.vertical.ResolvedOrientation.Rotate
+import androidx.text.vertical.ResolvedOrientation.TateChuYoko
+import androidx.text.vertical.ResolvedOrientation.Upright
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class TextRunsTest {
+    private val PREFIX = "PREFIX_PREFIX_PREFIX"
+    private val SUFFIX = "SUFFIX_SUFFIX_SUFFIX"
+    private val JAPANESE_TEXT = "あいうえお"
+    private val LATIN_TEXT = "abcde"
+
+    private val TEXT = PREFIX + LATIN_TEXT + JAPANESE_TEXT + SUFFIX
+    private val LATIN_START = PREFIX.length
+    private val LATIN_END = LATIN_START + LATIN_TEXT.length
+    private val JAPANESE_START = LATIN_END
+    private val JAPANESE_END = JAPANESE_START + JAPANESE_TEXT.length
+
+    private val ONE_EM = 10f // make 1em = 10px
+    private val HALF_EM = ONE_EM / 2
+
+    private val PAINT = TextPaint().apply { textSize = ONE_EM }
+
+    private fun getVerticalAdvance(text: String): Float {
+        PAINT.flags = PAINT.flags or Paint.VERTICAL_TEXT_FLAG
+        return PAINT.measureText(text)
+    }
+
+    private fun getHorizontalAdvance(text: String): Float {
+        PAINT.flags = PAINT.flags and Paint.VERTICAL_TEXT_FLAG.inv()
+        return PAINT.measureText(text)
+    }
+
+    private fun getHorizontalLineHeight(text: String): Float {
+        val fm = FontMetricsInt()
+        PAINT.getFontMetricsInt(text, 0, text.length, 0, text.length, false, fm)
+        return (fm.descent - fm.ascent).toFloat()
+    }
+
+    private fun createLayoutRun(
+        text: CharSequence,
+        start: Int,
+        end: Int,
+        orientation: ResolvedOrientation
+    ) = createLayoutRun(text, start, end, PAINT, orientation)
+
+    private class MockCanvas(val drawTextCallback: (CharSequence, Int, Int, Paint) -> Unit) :
+        Canvas() {
+        override fun drawText(
+            text: CharSequence,
+            start: Int,
+            end: Int,
+            x: Float,
+            y: Float,
+            paint: Paint
+        ) {
+            super.drawText(text, start, end, x, y, paint)
+            drawTextCallback(text, start, end, paint)
+        }
+    }
+
+    @Test
+    fun `Upright SingleStyle Latin`() {
+        createLayoutRun(TEXT, LATIN_START, LATIN_END, Upright).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(LATIN_END)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height).isEqualTo(getVerticalAdvance(LATIN_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset).isEqualTo(HALF_EM) // rightSide is half of 1em
+
+            draw(
+                MockCanvas { text, start, end, paint ->
+                    assertThat(text).isEqualTo(TEXT)
+                    assertThat(start).isEqualTo(LATIN_START)
+                    assertThat(end).isEqualTo(LATIN_END)
+                    assertThat(paint.hasVerticalTextFlag()).isTrue()
+                },
+                0f,
+                0f,
+                PAINT
+            )
+        }
+    }
+
+    @Test
+    fun `Upright SingleStyle Japanese`() {
+        createLayoutRun(TEXT, JAPANESE_START, JAPANESE_END, Upright).run {
+            assertThat(start).isEqualTo(JAPANESE_START)
+            assertThat(end).isEqualTo(JAPANESE_END)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height).isEqualTo(getVerticalAdvance(JAPANESE_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset).isEqualTo(HALF_EM) // rightSide is half of 1em
+
+            draw(
+                MockCanvas { text, start, end, paint ->
+                    assertThat(text).isEqualTo(TEXT)
+                    assertThat(start).isEqualTo(JAPANESE_START)
+                    assertThat(end).isEqualTo(JAPANESE_END)
+                    assertThat(paint.hasVerticalTextFlag()).isTrue()
+                },
+                0f,
+                0f,
+                PAINT
+            )
+        }
+    }
+
+    @Test
+    fun `Rotate SingleStyle Latin`() {
+        createLayoutRun(TEXT, LATIN_START, LATIN_END, Rotate).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(LATIN_END)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height).isEqualTo(getHorizontalAdvance(LATIN_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset).isEqualTo(HALF_EM) // rightSide is half of 1em
+
+            draw(
+                MockCanvas { text, start, end, paint ->
+                    assertThat(text).isEqualTo(TEXT)
+                    assertThat(start).isEqualTo(LATIN_START)
+                    assertThat(end).isEqualTo(LATIN_END)
+                    assertThat(paint.hasVerticalTextFlag()).isFalse()
+                },
+                0f,
+                0f,
+                PAINT
+            )
+        }
+    }
+
+    @Test
+    fun `Rotate SingleStyle Japanese`() {
+        createLayoutRun(TEXT, JAPANESE_START, JAPANESE_END, Rotate).run {
+            assertThat(start).isEqualTo(JAPANESE_START)
+            assertThat(end).isEqualTo(JAPANESE_END)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height).isEqualTo(getVerticalAdvance(JAPANESE_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset).isEqualTo(HALF_EM) // rightSide is half of 1em
+
+            draw(
+                MockCanvas { text, start, end, paint ->
+                    assertThat(text).isEqualTo(TEXT)
+                    assertThat(start).isEqualTo(JAPANESE_START)
+                    assertThat(end).isEqualTo(JAPANESE_END)
+                    assertThat(paint.hasVerticalTextFlag()).isFalse()
+                },
+                0f,
+                0f,
+                PAINT
+            )
+        }
+    }
+
+    @Test
+    fun `TateChuYoko SingleStyle Latin Can fit into 1em`() {
+        createLayoutRun(TEXT, LATIN_START, LATIN_START + 1, TateChuYoko).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(LATIN_START + 1)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height).isEqualTo(getHorizontalLineHeight(LATIN_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset).isEqualTo(HALF_EM) // rightSide is half of 1em
+
+            draw(
+                MockCanvas { text, start, end, paint ->
+                    assertThat(text).isEqualTo(TEXT)
+                    assertThat(start).isEqualTo(LATIN_START)
+                    assertThat(end).isEqualTo(LATIN_START + 1)
+                    assertThat(paint.hasVerticalTextFlag()).isFalse()
+                    assertThat(paint.textScaleX).isEqualTo(1f)
+                },
+                0f,
+                0f,
+                PAINT
+            )
+        }
+    }
+
+    @Test
+    fun `TateChuYoko SingleStyle Japanese Can fit into 1em`() {
+        createLayoutRun(TEXT, JAPANESE_START, JAPANESE_START + 1, TateChuYoko).run {
+            assertThat(start).isEqualTo(JAPANESE_START)
+            assertThat(end).isEqualTo(JAPANESE_START + 1)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height).isEqualTo(getHorizontalLineHeight(JAPANESE_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset).isEqualTo(HALF_EM) // rightSide is half of 1em
+
+            draw(
+                MockCanvas { text, start, end, paint ->
+                    assertThat(text).isEqualTo(TEXT)
+                    assertThat(start).isEqualTo(JAPANESE_START)
+                    assertThat(end).isEqualTo(JAPANESE_START + 1)
+                    assertThat(paint.hasVerticalTextFlag()).isFalse()
+                    assertThat(paint.textScaleX).isEqualTo(1f)
+                },
+                0f,
+                0f,
+                PAINT
+            )
+        }
+    }
+
+    @Test
+    fun `TateChuYoko SingleStyle Latin Stretch`() {
+        createLayoutRun(TEXT, LATIN_START, LATIN_START + 4, TateChuYoko).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(LATIN_START + 4)
+            assertThat(width).isEqualTo(ONE_EM * 1.1f) // allocate 1.1em for stretched text
+            assertThat(height).isEqualTo(getHorizontalLineHeight(LATIN_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM * 1.1f) // leftSide is half of 1.1em
+            assertThat(rightSideOffset).isEqualTo(HALF_EM * 1.1f) // rightSide is half of 1.1em
+
+            draw(
+                MockCanvas { text, start, end, paint ->
+                    assertThat(text).isEqualTo(TEXT)
+                    assertThat(start).isEqualTo(LATIN_START)
+                    assertThat(end).isEqualTo(LATIN_START + 4)
+                    assertThat(paint.hasVerticalTextFlag()).isFalse()
+                    assertThat(paint.textScaleX).isNotEqualTo(1f)
+                },
+                0f,
+                0f,
+                PAINT
+            )
+        }
+    }
+
+    @Test
+    fun `TateChuYoko SingleStyle Japanese Stretch`() {
+        createLayoutRun(TEXT, JAPANESE_START, JAPANESE_START + 4, TateChuYoko).run {
+            assertThat(start).isEqualTo(JAPANESE_START)
+            assertThat(end).isEqualTo(JAPANESE_START + 4)
+            assertThat(width).isEqualTo(ONE_EM * 1.1f) // allocate 1.1em for stretched text
+            assertThat(height).isEqualTo(getHorizontalLineHeight(JAPANESE_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM * 1.1f) // leftSide is half of 1.1em
+            assertThat(rightSideOffset).isEqualTo(HALF_EM * 1.1f) // rightSide is half of 1.1em
+
+            draw(
+                MockCanvas { text, start, end, paint ->
+                    assertThat(text).isEqualTo(TEXT)
+                    assertThat(start).isEqualTo(JAPANESE_START)
+                    assertThat(end).isEqualTo(JAPANESE_START + 4)
+                    assertThat(paint.hasVerticalTextFlag()).isFalse()
+                    assertThat(paint.textScaleX).isNotEqualTo(1f)
+                },
+                0f,
+                0f,
+                PAINT
+            )
+        }
+    }
+}
+
+private fun Paint.hasVerticalTextFlag() =
+    (flags and Paint.VERTICAL_TEXT_FLAG) == Paint.VERTICAL_TEXT_FLAG
diff --git a/text/text-vertical/src/androidTest/java/androidx/text/vertical/LineBreakerTest.kt b/text/text-vertical/src/androidTest/java/androidx/text/vertical/LineBreakerTest.kt
new file mode 100644
index 0000000..cf48b8f
--- /dev/null
+++ b/text/text-vertical/src/androidTest/java/androidx/text/vertical/LineBreakerTest.kt
@@ -0,0 +1,525 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Paint
+import android.text.SpannableString
+import android.text.TextPaint
+import androidx.text.vertical.TextOrientationSpan.TextCombineUpright
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+private const val SPAN_FLAG = SpannableString.SPAN_INCLUSIVE_EXCLUSIVE
+
+@RunWith(JUnit4::class)
+class LineBreakerTest {
+    private val PREFIX = "PREFIX_PREFIX_PREFIX"
+    private val SUFFIX = "SUFFIX_SUFFIX_SUFFIX"
+
+    private val EM = 10f // make 1em = 10px
+    private val HALF_EM = EM * 0.5f
+
+    private val PAINT = TextPaint().apply { textSize = EM }
+
+    private fun getVerticalAdvance(text: String): Float {
+        PAINT.flags = PAINT.flags or Paint.VERTICAL_TEXT_FLAG
+        return PAINT.measureText(text)
+    }
+
+    private fun getHorizontalAdvance(text: String, scaleFactor: Float = 1.0f): Float {
+        PAINT.flags = PAINT.flags and Paint.VERTICAL_TEXT_FLAG.inv()
+        PAINT.textSize = EM * scaleFactor
+        try {
+            return PAINT.measureText(text)
+        } finally {
+            PAINT.textSize = EM
+        }
+    }
+
+    private fun getHorizontalLineHeight(text: String): Float {
+        val fm = Paint.FontMetricsInt()
+        PAINT.getFontMetricsInt(text, 0, text.length, 0, text.length, false, fm)
+        return (fm.descent - fm.ascent).toFloat()
+    }
+
+    @Test
+    fun `BreakLine all upright Japanese`() {
+        val jpText = "吾輩は猫である。"
+        val text = PREFIX + jpText + SUFFIX
+        val jpStart = PREFIX.length
+        val jpEnd = jpStart + jpText.length
+        val breakText: (Float) -> LineBreaker.Result = { heightConstraint ->
+            LineBreaker.breakTextIntoLines(
+                text,
+                jpStart,
+                jpEnd,
+                PAINT,
+                heightConstraint,
+                TextOrientation.MIXED
+            )
+        }
+
+        // The following test verifies the behavior of breaking "吾輩は猫である。"
+        breakText(getVerticalAdvance(jpText)).also {
+            // ----
+            // 吾
+            // 輩
+            // は
+            // 猫
+            // で
+            // あ
+            // る
+            // 。
+            // ----
+            assertThat(it.lineCount).isEqualTo(1)
+            assertThat(it.width).isEqualTo(1 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 8)
+        }
+
+        breakText(getVerticalAdvance(jpText) * 0.9f).also {
+            // ----
+            // る吾
+            // 。輩
+            // 　は
+            // 　猫
+            // 　で
+            // 　あ
+            // ----
+            assertThat(it.lineCount).isEqualTo(2)
+            assertThat(it.width).isEqualTo(2 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineStart(1)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineEnd(1)).isEqualTo(jpStart + 8)
+        }
+
+        breakText(getVerticalAdvance(jpText) * 0.4f).also {
+            // ----
+            // る猫吾
+            // 。で輩
+            // 　あは
+            // ----
+            assertThat(it.lineCount).isEqualTo(3)
+            assertThat(it.width).isEqualTo(3 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 3)
+            assertThat(it.getLineStart(1)).isEqualTo(jpStart + 3)
+            assertThat(it.getLineEnd(1)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineStart(2)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineEnd(2)).isEqualTo(jpStart + 8)
+        }
+
+        breakText(getVerticalAdvance(jpText) * 0.25f).also {
+            // ----
+            // るでは吾
+            // 。あ猫輩
+            // ----
+            assertThat(it.lineCount).isEqualTo(4)
+            assertThat(it.width).isEqualTo(4 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 2)
+            assertThat(it.getLineStart(1)).isEqualTo(jpStart + 2)
+            assertThat(it.getLineEnd(1)).isEqualTo(jpStart + 4)
+            assertThat(it.getLineStart(2)).isEqualTo(jpStart + 4)
+            assertThat(it.getLineEnd(2)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineStart(3)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineEnd(3)).isEqualTo(jpStart + 8)
+        }
+
+        breakText(getVerticalAdvance(jpText) * 0.1f).also {
+            // ----
+            // 。るあで猫は輩吾
+            // ----
+            assertThat(it.lineCount).isEqualTo(8)
+            assertThat(it.width).isEqualTo(8 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 1)
+            assertThat(it.getLineStart(1)).isEqualTo(jpStart + 1)
+            assertThat(it.getLineEnd(1)).isEqualTo(jpStart + 2)
+            assertThat(it.getLineStart(2)).isEqualTo(jpStart + 2)
+            assertThat(it.getLineEnd(2)).isEqualTo(jpStart + 3)
+            assertThat(it.getLineStart(3)).isEqualTo(jpStart + 3)
+            assertThat(it.getLineEnd(3)).isEqualTo(jpStart + 4)
+            assertThat(it.getLineStart(4)).isEqualTo(jpStart + 4)
+            assertThat(it.getLineEnd(4)).isEqualTo(jpStart + 5)
+            assertThat(it.getLineStart(5)).isEqualTo(jpStart + 5)
+            assertThat(it.getLineEnd(5)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineStart(6)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineEnd(6)).isEqualTo(jpStart + 7)
+            assertThat(it.getLineStart(7)).isEqualTo(jpStart + 7)
+            assertThat(it.getLineEnd(7)).isEqualTo(jpStart + 8)
+        }
+    }
+
+    @Test
+    fun `BreakLine all rotate Latin`() {
+        val enText = "Hello, world."
+        val text = PREFIX + enText + SUFFIX
+        val enStart = PREFIX.length
+        val enEnd = enStart + enText.length
+        val breakText: (Float) -> LineBreaker.Result = { heightConstraint ->
+            LineBreaker.breakTextIntoLines(
+                text,
+                enStart,
+                enEnd,
+                PAINT,
+                heightConstraint,
+                TextOrientation.MIXED
+            )
+        }
+
+        // The following test verifies the behavior of breaking "Hello, World."
+        // Each letter are rotated.
+        breakText(getHorizontalAdvance(enText)).also {
+            // |Hello, World.|
+            // Note: the actual text is 90 degree rotated clockwise.
+            assertThat(it.lineCount).isEqualTo(1)
+            assertThat(it.width).isEqualTo(1 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(enStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(enStart + 13)
+        }
+
+        breakText(getHorizontalAdvance(enText) * 0.9f).also {
+            // |Hello,     |
+            // |World.     |
+            // Note: the actual text is 90 degree rotated clockwise.
+            assertThat(it.lineCount).isEqualTo(2)
+            assertThat(it.width).isEqualTo(2 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(enStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(enStart + 7)
+            assertThat(it.getLineStart(1)).isEqualTo(enStart + 7)
+            assertThat(it.getLineEnd(1)).isEqualTo(enStart + 13)
+        }
+
+        breakText(1.0f).also {
+            // |H|
+            // |e|
+            // |l|
+            // |l|
+            // |o|
+            // |,|
+            // | |  // TODO: The line end whitespace should not be counted line width.
+            // |W|
+            // |o|
+            // |r|
+            // |l|
+            // |d|
+            // |.|
+            // Note: the actual text is 90 degree rotated clockwise.
+            assertThat(it.lineCount).isEqualTo(13)
+            assertThat(it.width).isEqualTo(13 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(enStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(enStart + 1)
+            assertThat(it.getLineStart(1)).isEqualTo(enStart + 1)
+            assertThat(it.getLineEnd(1)).isEqualTo(enStart + 2)
+            assertThat(it.getLineStart(2)).isEqualTo(enStart + 2)
+            assertThat(it.getLineEnd(2)).isEqualTo(enStart + 3)
+            assertThat(it.getLineStart(3)).isEqualTo(enStart + 3)
+            assertThat(it.getLineEnd(3)).isEqualTo(enStart + 4)
+            assertThat(it.getLineStart(4)).isEqualTo(enStart + 4)
+            assertThat(it.getLineEnd(4)).isEqualTo(enStart + 5)
+            assertThat(it.getLineStart(5)).isEqualTo(enStart + 5)
+            assertThat(it.getLineEnd(5)).isEqualTo(enStart + 6)
+            assertThat(it.getLineStart(6)).isEqualTo(enStart + 6)
+            assertThat(it.getLineEnd(6)).isEqualTo(enStart + 7)
+            assertThat(it.getLineStart(7)).isEqualTo(enStart + 7)
+            assertThat(it.getLineEnd(7)).isEqualTo(enStart + 8)
+            assertThat(it.getLineStart(8)).isEqualTo(enStart + 8)
+            assertThat(it.getLineEnd(8)).isEqualTo(enStart + 9)
+            assertThat(it.getLineStart(9)).isEqualTo(enStart + 9)
+            assertThat(it.getLineEnd(9)).isEqualTo(enStart + 10)
+            assertThat(it.getLineStart(10)).isEqualTo(enStart + 10)
+            assertThat(it.getLineEnd(10)).isEqualTo(enStart + 11)
+            assertThat(it.getLineStart(11)).isEqualTo(enStart + 11)
+            assertThat(it.getLineEnd(11)).isEqualTo(enStart + 12)
+            assertThat(it.getLineStart(12)).isEqualTo(enStart + 12)
+            assertThat(it.getLineEnd(12)).isEqualTo(enStart + 13)
+        }
+    }
+
+    @Test
+    fun `BreakLine all upright Latin`() {
+        val enText = "Hello, World."
+        val text = PREFIX + enText + SUFFIX
+        val enStart = PREFIX.length
+        val enEnd = enStart + enText.length
+        val breakText: (Float) -> LineBreaker.Result = { heightConstraint ->
+            LineBreaker.breakTextIntoLines(
+                text,
+                enStart,
+                enEnd,
+                PAINT,
+                heightConstraint,
+                TextOrientation.UPRIGHT
+            )
+        }
+
+        breakText(getVerticalAdvance(enText)).also {
+            // --
+            // H
+            // e
+            // l
+            // l
+            // o
+            // ,
+            //
+            // W
+            // o
+            // r
+            // l
+            // d
+            // .
+            // --
+            assertThat(it.lineCount).isEqualTo(1)
+            assertThat(it.width).isEqualTo(1 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(enStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(enStart + 13)
+        }
+
+        breakText(getVerticalAdvance(enText) * 0.9f).also {
+            // --
+            // WH
+            // oe
+            // rl
+            // ll
+            // do
+            // .,
+            //
+            //
+            //
+            //
+            // --
+            assertThat(it.lineCount).isEqualTo(2)
+            assertThat(it.width).isEqualTo(2 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(enStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(enStart + 7)
+            assertThat(it.getLineStart(1)).isEqualTo(enStart + 7)
+            assertThat(it.getLineEnd(1)).isEqualTo(enStart + 13)
+        }
+
+        breakText(1.0f).also {
+            // -------------
+            // .dlroW olleH
+            // -------------
+            assertThat(it.lineCount).isEqualTo(13)
+            assertThat(it.width).isEqualTo(13 * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM)
+            assertThat(it.getLineStart(0)).isEqualTo(enStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(enStart + 1)
+            assertThat(it.getLineStart(1)).isEqualTo(enStart + 1)
+            assertThat(it.getLineEnd(1)).isEqualTo(enStart + 2)
+            assertThat(it.getLineStart(2)).isEqualTo(enStart + 2)
+            assertThat(it.getLineEnd(2)).isEqualTo(enStart + 3)
+            assertThat(it.getLineStart(3)).isEqualTo(enStart + 3)
+            assertThat(it.getLineEnd(3)).isEqualTo(enStart + 4)
+            assertThat(it.getLineStart(4)).isEqualTo(enStart + 4)
+            assertThat(it.getLineEnd(4)).isEqualTo(enStart + 5)
+            assertThat(it.getLineStart(5)).isEqualTo(enStart + 5)
+            assertThat(it.getLineEnd(5)).isEqualTo(enStart + 6)
+            assertThat(it.getLineStart(6)).isEqualTo(enStart + 6)
+            assertThat(it.getLineEnd(6)).isEqualTo(enStart + 7)
+            assertThat(it.getLineStart(7)).isEqualTo(enStart + 7)
+            assertThat(it.getLineEnd(7)).isEqualTo(enStart + 8)
+            assertThat(it.getLineStart(8)).isEqualTo(enStart + 8)
+            assertThat(it.getLineEnd(8)).isEqualTo(enStart + 9)
+            assertThat(it.getLineStart(9)).isEqualTo(enStart + 9)
+            assertThat(it.getLineEnd(9)).isEqualTo(enStart + 10)
+            assertThat(it.getLineStart(10)).isEqualTo(enStart + 10)
+            assertThat(it.getLineEnd(10)).isEqualTo(enStart + 11)
+            assertThat(it.getLineStart(11)).isEqualTo(enStart + 11)
+            assertThat(it.getLineEnd(11)).isEqualTo(enStart + 12)
+            assertThat(it.getLineStart(12)).isEqualTo(enStart + 12)
+            assertThat(it.getLineEnd(12)).isEqualTo(enStart + 13)
+        }
+    }
+
+    @Test
+    fun `BreakLine TateChuYoko`() {
+        val jpDateText = "2024年12月25日"
+        val jpStart = PREFIX.length
+        val jpEnd = jpStart + jpDateText.length
+        val spanned =
+            SpannableString(PREFIX + jpDateText + SUFFIX).apply {
+                setSpan(TextCombineUpright(), jpStart, jpStart + 4, SPAN_FLAG) // 2024
+                setSpan(TextCombineUpright(), jpStart + 5, jpStart + 7, SPAN_FLAG) // 12
+                setSpan(TextCombineUpright(), jpStart + 8, jpStart + 10, SPAN_FLAG) // 25
+            }
+        val breakText: (Float) -> LineBreaker.Result = { heightConstraint ->
+            LineBreaker.breakTextIntoLines(
+                spanned,
+                jpStart,
+                jpEnd,
+                PAINT,
+                heightConstraint,
+                TextOrientation.MIXED
+            )
+        }
+
+        val h2024 = getHorizontalLineHeight("2024")
+        val hYear = getVerticalAdvance("年")
+        val h12 = getHorizontalLineHeight("12")
+        val hMonth = getVerticalAdvance("月")
+        val h25 = getHorizontalLineHeight("25")
+        val hDay = getVerticalAdvance("日")
+
+        breakText(h2024 + hYear + h12 + hMonth + h25 + hDay).also {
+            // ----
+            // [2024]
+            // 年
+            // [12]
+            // 月
+            // [25]
+            // 日
+            // ----
+            assertThat(it.lineCount).isEqualTo(1)
+            assertThat(it.width).isEqualTo(1.1f * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM * 1.1f)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM * 1.1f)
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 11)
+        }
+
+        breakText(h2024 + hYear + h12 + hMonth).also {
+            // ----
+            // [25]　[2024]
+            // 日　　　年
+            // 　　　　[12]
+            // 　　　　月
+            // ----
+            assertThat(it.lineCount).isEqualTo(2)
+            assertThat(it.width).isEqualTo(2 * 1.1f * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM * 1.1f)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM * 1.1f)
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 8)
+            assertThat(it.getLineStart(1)).isEqualTo(jpStart + 8)
+            assertThat(it.getLineEnd(1)).isEqualTo(jpStart + 11)
+        }
+
+        breakText(h2024 * 0.9f).also {
+            // ----
+            // 日[25]月[12]年[2024]
+            // ----
+            assertThat(it.lineCount).isEqualTo(6)
+            assertThat(it.width).isEqualTo(6 * 1.1f * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM * 1.1f)
+            assertThat(it.lineRightSide).isEqualTo(HALF_EM * 1.1f)
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 4)
+            assertThat(it.getLineStart(1)).isEqualTo(jpStart + 4)
+            assertThat(it.getLineEnd(1)).isEqualTo(jpStart + 5)
+            assertThat(it.getLineStart(2)).isEqualTo(jpStart + 5)
+            assertThat(it.getLineEnd(2)).isEqualTo(jpStart + 7)
+            assertThat(it.getLineStart(3)).isEqualTo(jpStart + 7)
+            assertThat(it.getLineEnd(3)).isEqualTo(jpStart + 8)
+            assertThat(it.getLineStart(4)).isEqualTo(jpStart + 8)
+            assertThat(it.getLineEnd(4)).isEqualTo(jpStart + 10)
+            assertThat(it.getLineStart(5)).isEqualTo(jpStart + 10)
+            assertThat(it.getLineEnd(5)).isEqualTo(jpStart + 11)
+        }
+    }
+
+    @Test
+    fun `BreakLine Ruby`() {
+        val jpText = "吾輩は猫である。"
+        val jpStart = PREFIX.length
+        val jpEnd = jpStart + jpText.length
+        // Set "わがはい" ruby to "吾輩".
+        val spanned =
+            SpannableString(PREFIX + jpText + SUFFIX).apply {
+                setSpan(RubySpan.Builder("わがはい").build(), jpStart, jpStart + 2, SPAN_FLAG) // 吾輩
+            }
+        val breakText: (Float) -> LineBreaker.Result = { heightConstraint ->
+            LineBreaker.breakTextIntoLines(
+                spanned,
+                jpStart,
+                jpEnd,
+                PAINT,
+                heightConstraint,
+                TextOrientation.MIXED
+            )
+        }
+
+        breakText(getVerticalAdvance(jpText)).also {
+            // ----
+            // 吾
+            // 輩
+            // は
+            // 猫
+            // で
+            // あ
+            // る
+            // 。
+            // ----
+            assertThat(it.lineCount).isEqualTo(1)
+            assertThat(it.width).isEqualTo(1.5f * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(1 * EM) // 0.5em for right side, 0.5em for ruby
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 8)
+        }
+
+        breakText(getVerticalAdvance(jpText) * 0.1f).also {
+            // ----
+            // 。るあで猫は吾
+            // 　　　　　　輩
+            // ----
+            assertThat(it.lineCount).isEqualTo(7)
+            assertThat(it.width).isEqualTo(7 * 1.5f * EM)
+            assertThat(it.lineLeftSide).isEqualTo(-HALF_EM)
+            assertThat(it.lineRightSide).isEqualTo(1 * EM) // 0.5em for right side, 0.5em for ruby
+            assertThat(it.getLineStart(0)).isEqualTo(jpStart)
+            assertThat(it.getLineEnd(0)).isEqualTo(jpStart + 2)
+            assertThat(it.getLineStart(1)).isEqualTo(jpStart + 2)
+            assertThat(it.getLineEnd(1)).isEqualTo(jpStart + 3)
+            assertThat(it.getLineStart(2)).isEqualTo(jpStart + 3)
+            assertThat(it.getLineEnd(2)).isEqualTo(jpStart + 4)
+            assertThat(it.getLineStart(3)).isEqualTo(jpStart + 4)
+            assertThat(it.getLineEnd(3)).isEqualTo(jpStart + 5)
+            assertThat(it.getLineStart(4)).isEqualTo(jpStart + 5)
+            assertThat(it.getLineEnd(4)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineStart(5)).isEqualTo(jpStart + 6)
+            assertThat(it.getLineEnd(5)).isEqualTo(jpStart + 7)
+            assertThat(it.getLineStart(6)).isEqualTo(jpStart + 7)
+            assertThat(it.getLineEnd(6)).isEqualTo(jpStart + 8)
+        }
+    }
+}
diff --git a/text/text-vertical/src/androidTest/java/androidx/text/vertical/LineLayoutTest.kt b/text/text-vertical/src/androidTest/java/androidx/text/vertical/LineLayoutTest.kt
new file mode 100644
index 0000000..8cda6e0
--- /dev/null
+++ b/text/text-vertical/src/androidTest/java/androidx/text/vertical/LineLayoutTest.kt
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Paint
+import android.graphics.Paint.FontMetricsInt
+import android.text.SpannableString
+import android.text.TextPaint
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+private const val SPAN_FLAG = SpannableString.SPAN_INCLUSIVE_EXCLUSIVE
+
+@RunWith(JUnit4::class)
+class LineLayoutRunTest {
+    private val PREFIX = "PREFIX_PREFIX_PREFIX"
+    private val SUFFIX = "SUFFIX_SUFFIX_SUFFIX"
+    private val JAPANESE_TEXT = "あいうえお"
+    private val LATIN_TEXT = "abcde"
+
+    private val TEXT = PREFIX + LATIN_TEXT + JAPANESE_TEXT + SUFFIX
+    private val LATIN_START = PREFIX.length
+    private val LATIN_END = LATIN_START + LATIN_TEXT.length
+    private val JAPANESE_START = LATIN_END
+    private val JAPANESE_END = JAPANESE_START + JAPANESE_TEXT.length
+
+    private val ONE_EM = 10f // make 1em = 10px
+    private val HALF_EM = ONE_EM / 2
+
+    private val PAINT = TextPaint().apply { textSize = ONE_EM }
+
+    private fun getVerticalAdvance(text: String): Float {
+        PAINT.flags = PAINT.flags or Paint.VERTICAL_TEXT_FLAG
+        return PAINT.measureText(text)
+    }
+
+    private fun getHorizontalAdvance(text: String): Float {
+        PAINT.flags = PAINT.flags and Paint.VERTICAL_TEXT_FLAG.inv()
+        return PAINT.measureText(text)
+    }
+
+    private fun getHorizontalLineHeight(text: String): Float {
+        val fm = FontMetricsInt()
+        PAINT.getFontMetricsInt(text, 0, text.length, 0, text.length, false, fm)
+        return (fm.descent - fm.ascent).toFloat()
+    }
+
+    private fun createLayoutRun(
+        text: CharSequence,
+        start: Int,
+        end: Int,
+        orientation: ResolvedOrientation
+    ) = createLayoutRun(text, start, end, PAINT, orientation)
+
+    @Test
+    fun `LineLayout plain text with Mixed`() {
+        createLineLayout(TEXT, LATIN_START, JAPANESE_END, PAINT, TextOrientation.MIXED).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(JAPANESE_END)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height)
+                .isEqualTo(getHorizontalAdvance(LATIN_TEXT) + getVerticalAdvance(JAPANESE_TEXT))
+            assertThat(leftSide).isEqualTo(-HALF_EM)
+            assertThat(rightSide).isEqualTo(HALF_EM)
+            assertThat(runs.size).isEqualTo(2)
+            assertThat(runs[0].start).isEqualTo(LATIN_START)
+            assertThat(runs[0].end).isEqualTo(LATIN_END)
+            assertThat(runs[0]).isInstanceOf(RotateLayoutRun::class.java)
+            assertThat(runs[1].start).isEqualTo(JAPANESE_START)
+            assertThat(runs[1].end).isEqualTo(JAPANESE_END)
+            assertThat(runs[1]).isInstanceOf(UprightLayoutRun::class.java)
+        }
+    }
+
+    @Test
+    fun `LineLayout plain text with Upright`() {
+        createLineLayout(TEXT, LATIN_START, JAPANESE_END, PAINT, TextOrientation.UPRIGHT).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(JAPANESE_END)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height)
+                .isEqualTo(getVerticalAdvance(LATIN_TEXT) + getVerticalAdvance(JAPANESE_TEXT))
+            assertThat(leftSide).isEqualTo(-HALF_EM)
+            assertThat(rightSide).isEqualTo(HALF_EM)
+            assertThat(runs.size).isEqualTo(1)
+            assertThat(runs[0].start).isEqualTo(LATIN_START)
+            assertThat(runs[0].end).isEqualTo(JAPANESE_END)
+            assertThat(runs[0]).isInstanceOf(UprightLayoutRun::class.java)
+        }
+    }
+
+    @Test
+    fun `LineLayout plain text with Sideways`() {
+        createLineLayout(TEXT, LATIN_START, JAPANESE_END, PAINT, TextOrientation.SIDEWAYS).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(JAPANESE_END)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height)
+                .isEqualTo(getHorizontalAdvance(LATIN_TEXT) + getHorizontalAdvance(JAPANESE_TEXT))
+            assertThat(leftSide).isEqualTo(-HALF_EM)
+            assertThat(rightSide).isEqualTo(HALF_EM)
+            assertThat(runs.size).isEqualTo(1)
+            assertThat(runs[0].start).isEqualTo(LATIN_START)
+            assertThat(runs[0].end).isEqualTo(JAPANESE_END)
+            assertThat(runs[0]).isInstanceOf(RotateLayoutRun::class.java)
+        }
+    }
+
+    @Test
+    fun `LineLayout span override text with Sideways`() {
+        val spanned =
+            SpannableString(TEXT).apply {
+                setSpan(TextOrientationSpan.Sideways(), JAPANESE_START, JAPANESE_END, SPAN_FLAG)
+            }
+        createLineLayout(spanned, LATIN_START, JAPANESE_END, PAINT, TextOrientation.MIXED).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(JAPANESE_END)
+            assertThat(width).isEqualTo(ONE_EM) // width is 1em.
+            assertThat(height)
+                .isEqualTo(getHorizontalAdvance(LATIN_TEXT) + getHorizontalAdvance(JAPANESE_TEXT))
+            assertThat(leftSide).isEqualTo(-HALF_EM)
+            assertThat(rightSide).isEqualTo(HALF_EM)
+            assertThat(runs.size).isEqualTo(1)
+            assertThat(runs[0].start).isEqualTo(LATIN_START)
+            assertThat(runs[0].end).isEqualTo(JAPANESE_END)
+            assertThat(runs[0]).isInstanceOf(RotateLayoutRun::class.java)
+        }
+    }
+
+    @Test
+    fun `LineLayout span override text with TateChuYoko`() {
+        val spanned =
+            SpannableString(TEXT).apply {
+                setSpan(TextOrientationSpan.TextCombineUpright(), LATIN_START, LATIN_END, SPAN_FLAG)
+            }
+        createLineLayout(spanned, LATIN_START, JAPANESE_END, PAINT, TextOrientation.MIXED).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(JAPANESE_END)
+            // Overall line width is extended to 1.1em because of the long TateChuYoko span.
+            assertThat(width).isEqualTo(ONE_EM * 1.1f) // width is 1em.
+            assertThat(height)
+                .isEqualTo(getHorizontalLineHeight(LATIN_TEXT) + getVerticalAdvance(JAPANESE_TEXT))
+
+            // Overall line sides are extended to 1.1em because of the long TateChuYoko span.
+            assertThat(leftSide).isEqualTo(-HALF_EM * 1.1f)
+            assertThat(rightSide).isEqualTo(HALF_EM * 1.1f)
+            assertThat(runs.size).isEqualTo(2)
+            assertThat(runs[0].start).isEqualTo(LATIN_START)
+            assertThat(runs[0].end).isEqualTo(LATIN_END)
+            assertThat(runs[0]).isInstanceOf(TateChuYokoLayoutRun::class.java)
+            assertThat(runs[1].start).isEqualTo(JAPANESE_START)
+            assertThat(runs[1].end).isEqualTo(JAPANESE_END)
+            assertThat(runs[1]).isInstanceOf(UprightLayoutRun::class.java)
+        }
+    }
+}
diff --git a/text/text-vertical/src/androidTest/java/androidx/text/vertical/OrientationsTest.kt b/text/text-vertical/src/androidTest/java/androidx/text/vertical/OrientationsTest.kt
new file mode 100644
index 0000000..1572e41
--- /dev/null
+++ b/text/text-vertical/src/androidTest/java/androidx/text/vertical/OrientationsTest.kt
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import android.text.SpannableString
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.text.vertical.OrientationMode
+import androidx.text.vertical.ResolvedOrientation
+import androidx.text.vertical.TextOrientation
+import androidx.text.vertical.TextOrientationSpan
+import androidx.text.vertical.forEachOrientation
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val SPAN_FLAG = SpannableString.SPAN_INCLUSIVE_EXCLUSIVE
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class OrientationsTest {
+    private sealed interface Run
+
+    private data class Upright(val start: Int, val end: Int) : Run
+
+    private data class Rotate(val start: Int, val end: Int) : Run
+
+    private data class TateChuYoko(val start: Int, val end: Int) : Run
+
+    private fun resolve(
+        text: CharSequence,
+        start: Int = 0,
+        end: Int = text.length,
+        @OrientationMode textOrientation: Int = TextOrientation.MIXED
+    ): List<Run> {
+        val out = mutableListOf<Run>()
+        forEachOrientation(text, start, end, textOrientation) { oStart, oEnd, orientation ->
+            when (orientation) {
+                ResolvedOrientation.Upright -> out.add(Upright(oStart, oEnd))
+                ResolvedOrientation.Rotate -> out.add(Rotate(oStart, oEnd))
+                ResolvedOrientation.TateChuYoko -> out.add(TateChuYoko(oStart, oEnd))
+            }
+        }
+        return out
+    }
+
+    private fun resolve(
+        text: CharSequence,
+        @OrientationMode textOrientation: Int = TextOrientation.MIXED
+    ) = resolve(text, 0, text.length, textOrientation)
+
+    @Test
+    fun emptyText() {
+        // Empty text
+        assertThat(resolve("")).isEmpty()
+        assertThat(resolve("", 0, 0)).isEmpty()
+
+        // Empty range
+        assertThat(resolve("abc", 0, 0)).isEmpty()
+        assertThat(resolve("abc", 1, 1)).isEmpty()
+
+        // Reversed range (invalid range)
+        assertThat(resolve("abc", 2, 1)).isEmpty()
+    }
+
+    @Test
+    fun noOverrideText_MixedOrientation() {
+        // Whole text
+        // Japanese letters: resolved to upright.
+        var runs = resolve("あいうえお")
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(0, 5))
+
+        // English letters: resolved to Rotate.
+        runs = resolve("abcde")
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(0, 5))
+
+        // Japanese and English mixed text: resolve as multiple runs
+        runs = resolve("あいうえおabcde")
+        assertThat(runs.size).isEqualTo(2)
+        assertThat(runs[0]).isEqualTo(Upright(0, 5))
+        assertThat(runs[1]).isEqualTo(Rotate(5, 10))
+
+        // Substring
+        runs = resolve("あいうえお", 1, 3)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(1, 3))
+
+        runs = resolve("abcde", 1, 3)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(1, 3))
+
+        runs = resolve("あいうえおabcde", 4, 7)
+        assertThat(runs.size).isEqualTo(2)
+        assertThat(runs[0]).isEqualTo(Upright(4, 5))
+        assertThat(runs[1]).isEqualTo(Rotate(5, 7))
+    }
+
+    @Test
+    fun noOverrideText_UprightOrientation() {
+        var runs = resolve("あいうえお", TextOrientation.UPRIGHT)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(0, 5))
+
+        runs = resolve("abcde", TextOrientation.UPRIGHT)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(0, 5))
+
+        runs = resolve("あいうえおabcde", TextOrientation.UPRIGHT)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(0, 10))
+
+        // Substring
+        runs = resolve("あいうえお", 1, 3, TextOrientation.UPRIGHT)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(1, 3))
+
+        runs = resolve("abcde", 1, 3, TextOrientation.UPRIGHT)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(1, 3))
+
+        runs = resolve("あいうえおabcde", 4, 7, textOrientation = TextOrientation.UPRIGHT)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(4, 7))
+    }
+
+    @Test
+    fun noOverrideText_SidewaysOrientation() {
+        var runs = resolve("あいうえお", TextOrientation.SIDEWAYS)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(0, 5))
+
+        runs = resolve("abcde", TextOrientation.SIDEWAYS)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(0, 5))
+
+        runs = resolve("あいうえおabcde", TextOrientation.SIDEWAYS)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(0, 10))
+
+        // Substring
+        runs = resolve("あいうえお", 1, 3, TextOrientation.SIDEWAYS)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(1, 3))
+
+        runs = resolve("abcde", 1, 3, TextOrientation.SIDEWAYS)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(1, 3))
+
+        runs = resolve("あいうえおabcde", 4, 7, TextOrientation.SIDEWAYS)
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(4, 7))
+    }
+
+    @Test
+    fun overrideText_UprightOverride() {
+        var runs =
+            resolve(
+                SpannableString("あいうえお").apply {
+                    setSpan(TextOrientationSpan.Upright(), 1, 2, SPAN_FLAG)
+                }
+            )
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Upright(0, 5))
+
+        runs =
+            resolve(
+                SpannableString("abcde").apply {
+                    setSpan(TextOrientationSpan.Upright(), 1, 2, SPAN_FLAG)
+                }
+            )
+        assertThat(runs.size).isEqualTo(3)
+        assertThat(runs[0]).isEqualTo(Rotate(0, 1))
+        assertThat(runs[1]).isEqualTo(Upright(1, 2))
+        assertThat(runs[2]).isEqualTo(Rotate(2, 5))
+
+        runs =
+            resolve(
+                SpannableString("あいうえおabcde").apply {
+                    setSpan(TextOrientationSpan.Upright(), 4, 7, SPAN_FLAG)
+                }
+            )
+        assertThat(runs.size).isEqualTo(2)
+        assertThat(runs[0]).isEqualTo(Upright(0, 7))
+        assertThat(runs[1]).isEqualTo(Rotate(7, 10))
+    }
+
+    @Test
+    fun overrideText_SidewaysOverride() {
+        var runs =
+            resolve(
+                SpannableString("あいうえお").apply {
+                    setSpan(TextOrientationSpan.Sideways(), 1, 2, SPAN_FLAG)
+                }
+            )
+        assertThat(runs.size).isEqualTo(3)
+        assertThat(runs[0]).isEqualTo(Upright(0, 1))
+        assertThat(runs[1]).isEqualTo(Rotate(1, 2))
+        assertThat(runs[2]).isEqualTo(Upright(2, 5))
+
+        runs =
+            resolve(
+                SpannableString("abcde").apply {
+                    setSpan(TextOrientationSpan.Sideways(), 1, 2, SPAN_FLAG)
+                }
+            )
+        assertThat(runs.size).isEqualTo(1)
+        assertThat(runs[0]).isEqualTo(Rotate(0, 5))
+
+        runs =
+            resolve(
+                SpannableString("あいうえおabcde").apply {
+                    setSpan(TextOrientationSpan.Sideways(), 4, 7, SPAN_FLAG)
+                }
+            )
+        assertThat(runs.size).isEqualTo(2)
+        assertThat(runs[0]).isEqualTo(Upright(0, 4))
+        assertThat(runs[1]).isEqualTo(Rotate(4, 10))
+    }
+
+    @Test
+    fun tateChuToko() {
+        var runs =
+            resolve(
+                SpannableString("abcde").apply {
+                    setSpan(TextOrientationSpan.TextCombineUpright(), 1, 2, SPAN_FLAG)
+                }
+            )
+        assertThat(runs.size).isEqualTo(3)
+        assertThat(runs[0]).isEqualTo(Rotate(0, 1))
+        assertThat(runs[1]).isEqualTo(TateChuYoko(1, 2))
+        assertThat(runs[2]).isEqualTo(Rotate(2, 5))
+
+        // TateChuYoko should not be extended even if they are connected.
+        runs =
+            resolve(
+                SpannableString("abcde").apply {
+                    setSpan(TextOrientationSpan.TextCombineUpright(), 1, 2, SPAN_FLAG)
+                    setSpan(TextOrientationSpan.TextCombineUpright(), 2, 4, SPAN_FLAG)
+                }
+            )
+        assertThat(runs.size).isEqualTo(4)
+        assertThat(runs[0]).isEqualTo(Rotate(0, 1))
+        assertThat(runs[1]).isEqualTo(TateChuYoko(1, 2))
+        assertThat(runs[2]).isEqualTo(TateChuYoko(2, 4))
+        assertThat(runs[3]).isEqualTo(Rotate(4, 5))
+    }
+}
diff --git a/text/text-vertical/src/androidTest/java/androidx/text/vertical/RubyTest.kt b/text/text-vertical/src/androidTest/java/androidx/text/vertical/RubyTest.kt
new file mode 100644
index 0000000..c18521a
--- /dev/null
+++ b/text/text-vertical/src/androidTest/java/androidx/text/vertical/RubyTest.kt
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.text.SpannableString
+import android.text.TextPaint
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+private const val SPAN_FLAG = SpannableString.SPAN_INCLUSIVE_EXCLUSIVE
+
+class RubyTest {
+    private val PREFIX = "PREFIX_PREFIX_PREFIX"
+    private val SUFFIX = "SUFFIX_SUFFIX_SUFFIX"
+    private val LATIN_TEXT = "abcde"
+    private val RUBY_TEXT = "ABCDE"
+
+    private val TEXT = PREFIX + LATIN_TEXT + SUFFIX
+    private val LATIN_START = PREFIX.length
+    private val LATIN_END = LATIN_START + LATIN_TEXT.length
+
+    private val ONE_EM = 10f // make 1em = 10px
+    private val HALF_EM = ONE_EM / 2
+
+    private val PAINT = TextPaint().apply { textSize = ONE_EM }
+
+    private fun getVerticalAdvance(text: String, scaleFactor: Float = 1.0f): Float {
+        PAINT.flags = PAINT.flags or Paint.VERTICAL_TEXT_FLAG
+        PAINT.textSize = ONE_EM * scaleFactor
+        try {
+            return PAINT.measureText(text)
+        } finally {
+            PAINT.textSize = ONE_EM
+        }
+    }
+
+    private fun getHorizontalAdvance(text: String, scaleFactor: Float = 1.0f): Float {
+        PAINT.flags = PAINT.flags and Paint.VERTICAL_TEXT_FLAG.inv()
+        PAINT.textSize = ONE_EM * scaleFactor
+        try {
+            return PAINT.measureText(text)
+        } finally {
+            PAINT.textSize = ONE_EM
+        }
+    }
+
+    private class MockCanvas() : Canvas() {
+        data class DrawTextRunCall(
+            val text: CharSequence,
+            val start: Int,
+            val end: Int,
+            val paint: Paint
+        )
+
+        val invocations = mutableListOf<DrawTextRunCall>()
+
+        override fun drawText(
+            text: CharSequence,
+            start: Int,
+            end: Int,
+            x: Float,
+            y: Float,
+            paint: Paint
+        ) {
+            super.drawText(text, start, end, x, y, paint)
+            invocations.add(DrawTextRunCall(text, start, end, Paint(paint)))
+        }
+    }
+
+    @Test
+    fun `Ruby Builder build and get - default`() {
+        RubySpan.Builder(RUBY_TEXT).build().run {
+            assertThat(text).isEqualTo(RUBY_TEXT)
+            assertThat(orientation).isEqualTo(TextOrientation.MIXED)
+            assertThat(textScale).isEqualTo(0.5f)
+        }
+    }
+
+    @Test
+    fun `Ruby Builder build and get - customize`() {
+        RubySpan.Builder(RUBY_TEXT)
+            .setOrientation(TextOrientation.UPRIGHT)
+            .setTextScale(0.3f)
+            .build()
+            .run {
+                assertThat(text).isEqualTo(RUBY_TEXT)
+                assertThat(orientation).isEqualTo(TextOrientation.UPRIGHT)
+                assertThat(textScale).isEqualTo(0.3f)
+            }
+    }
+
+    @Test
+    fun `RubyLayout create - Ruby is shorter than base text`() {
+        val rubySpan = RubySpan.Builder(RUBY_TEXT).build()
+        RubyLayoutRun(TEXT, LATIN_START, LATIN_END, TextOrientation.MIXED, PAINT, rubySpan).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(LATIN_END)
+            assertThat(width).isEqualTo(ONE_EM * 1.5f) // 1em for base text, 0.5em for ruby.
+            // Since the ruby is shorter than base text, the base text is height for the run.
+            assertThat(height).isEqualTo(getHorizontalAdvance(LATIN_TEXT))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset)
+                .isEqualTo(ONE_EM) // right half of 1em + 0.5em for ruby width.
+
+            val mock = MockCanvas()
+            draw(mock, 0f, 0f, PAINT)
+            assertThat(mock.invocations.size).isEqualTo(2)
+            val bodyIndex = if (mock.invocations[0].text == TEXT) 0 else 1
+            val rubyIndex = if (bodyIndex == 0) 1 else 0
+
+            mock.invocations[bodyIndex].run {
+                assertThat(start).isEqualTo(LATIN_START)
+                assertThat(end).isEqualTo(LATIN_END)
+                assertThat(paint.hasVerticalTextFlag()).isFalse()
+                assertThat(paint.textSize).isEqualTo(PAINT.textSize)
+            }
+            mock.invocations[rubyIndex].run {
+                assertThat(start).isEqualTo(0)
+                assertThat(end).isEqualTo(RUBY_TEXT.length)
+                assertThat(paint.hasVerticalTextFlag()).isFalse()
+                assertThat(paint.textSize).isEqualTo(PAINT.textSize * 0.5f)
+            }
+        }
+    }
+
+    @Test
+    fun `RubyLayout create - Ruby is longer than base text`() {
+        val LONG_RUBY_TEXT = RUBY_TEXT.repeat(10)
+        val rubySpan = RubySpan.Builder(LONG_RUBY_TEXT).build()
+        RubyLayoutRun(TEXT, LATIN_START, LATIN_END, TextOrientation.MIXED, PAINT, rubySpan).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(LATIN_END)
+            assertThat(width).isEqualTo(ONE_EM * 1.5f) // 1em for base text, 0.5em for ruby.
+            // Since the ruby is longer than base text, the ruby text is height for the run.
+            assertThat(height).isEqualTo(getHorizontalAdvance(LONG_RUBY_TEXT, 0.5f /* scale */))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset)
+                .isEqualTo(ONE_EM) // right half of 1em + 0.5em for ruby width.
+
+            val mock = MockCanvas()
+            draw(mock, 0f, 0f, PAINT)
+            assertThat(mock.invocations.size).isEqualTo(2)
+            val bodyIndex = if (mock.invocations[0].text == TEXT) 0 else 1
+            val rubyIndex = if (bodyIndex == 0) 1 else 0
+
+            mock.invocations[bodyIndex].run {
+                assertThat(start).isEqualTo(LATIN_START)
+                assertThat(end).isEqualTo(LATIN_END)
+                assertThat(paint.hasVerticalTextFlag()).isFalse()
+                assertThat(paint.textSize).isEqualTo(PAINT.textSize)
+            }
+            mock.invocations[rubyIndex].run {
+                assertThat(start).isEqualTo(0)
+                assertThat(end).isEqualTo(LONG_RUBY_TEXT.length)
+                assertThat(paint.hasVerticalTextFlag()).isFalse()
+                assertThat(paint.textSize).isEqualTo(PAINT.textSize * 0.5f)
+            }
+        }
+    }
+
+    @Test
+    fun `RubyLayout create - Ruby upright orientation`() {
+        val LONG_RUBY_TEXT = RUBY_TEXT.repeat(10)
+        val rubySpan =
+            RubySpan.Builder(LONG_RUBY_TEXT).setOrientation(TextOrientation.UPRIGHT).build()
+        RubyLayoutRun(TEXT, LATIN_START, LATIN_END, TextOrientation.MIXED, PAINT, rubySpan).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(LATIN_END)
+            assertThat(width).isEqualTo(ONE_EM * 1.5f) // 1em for base text, 0.5em for ruby.
+            // The ruby text is layout with UPRIGHT orientation. Therefore, the vertical advance
+            // is used for the height.
+            assertThat(height).isEqualTo(getVerticalAdvance(LONG_RUBY_TEXT, 0.5f /* scale */))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            assertThat(rightSideOffset)
+                .isEqualTo(ONE_EM) // right half of 1em + 0.5em for ruby width.
+
+            val mock = MockCanvas()
+            draw(mock, 0f, 0f, PAINT)
+            assertThat(mock.invocations.size).isEqualTo(2)
+            val bodyIndex = if (mock.invocations[0].text == TEXT) 0 else 1
+            val rubyIndex = if (bodyIndex == 0) 1 else 0
+
+            mock.invocations[bodyIndex].run {
+                assertThat(start).isEqualTo(LATIN_START)
+                assertThat(end).isEqualTo(LATIN_END)
+                assertThat(paint.hasVerticalTextFlag()).isFalse()
+                assertThat(paint.textSize).isEqualTo(PAINT.textSize)
+            }
+            mock.invocations[rubyIndex].run {
+                assertThat(start).isEqualTo(0)
+                assertThat(end).isEqualTo(LONG_RUBY_TEXT.length)
+                assertThat(paint.hasVerticalTextFlag()).isTrue()
+                assertThat(paint.textSize).isEqualTo(PAINT.textSize * 0.5f)
+            }
+        }
+    }
+
+    @Test
+    fun `RubyLayout create - Ruby scale`() {
+        val LONG_RUBY_TEXT = RUBY_TEXT.repeat(10)
+        val rubySpan = RubySpan.Builder(LONG_RUBY_TEXT).setTextScale(0.3f).build()
+        RubyLayoutRun(TEXT, LATIN_START, LATIN_END, TextOrientation.MIXED, PAINT, rubySpan).run {
+            assertThat(start).isEqualTo(LATIN_START)
+            assertThat(end).isEqualTo(LATIN_END)
+            assertThat(width).isEqualTo(ONE_EM * 1.3f) // 1em for base text, 0.5em for ruby.
+            // The ruby text is layout with UPRIGHT orientation. Therefore, the vertical advance
+            // is used for the height.
+            assertThat(height).isEqualTo(getHorizontalAdvance(LONG_RUBY_TEXT, 0.3f /* scale */))
+            assertThat(leftSideOffset).isEqualTo(-HALF_EM) // leftSide is half of 1em
+            // right half of 1em + 0.5em for ruby width.
+            assertThat(rightSideOffset).isEqualTo(HALF_EM + 0.3f * ONE_EM)
+
+            val mock = MockCanvas()
+            draw(mock, 0f, 0f, PAINT)
+            assertThat(mock.invocations.size).isEqualTo(2)
+            val bodyIndex = if (mock.invocations[0].text == TEXT) 0 else 1
+            val rubyIndex = if (bodyIndex == 0) 1 else 0
+
+            mock.invocations[bodyIndex].run {
+                assertThat(start).isEqualTo(LATIN_START)
+                assertThat(end).isEqualTo(LATIN_END)
+                assertThat(paint.hasVerticalTextFlag()).isFalse()
+                assertThat(paint.textSize).isEqualTo(PAINT.textSize)
+            }
+            mock.invocations[rubyIndex].run {
+                assertThat(start).isEqualTo(0)
+                assertThat(end).isEqualTo(LONG_RUBY_TEXT.length)
+                assertThat(paint.hasVerticalTextFlag()).isFalse()
+                assertThat(paint.textSize).isEqualTo(PAINT.textSize * 0.3f)
+            }
+        }
+    }
+}
+
+private fun Paint.hasVerticalTextFlag() =
+    (flags and Paint.VERTICAL_TEXT_FLAG) == Paint.VERTICAL_TEXT_FLAG
diff --git a/text/text-vertical/src/androidTest/java/androidx/text/vertical/VerticalTextLayoutTest.kt b/text/text-vertical/src/androidTest/java/androidx/text/vertical/VerticalTextLayoutTest.kt
new file mode 100644
index 0000000..8d74ca0
--- /dev/null
+++ b/text/text-vertical/src/androidTest/java/androidx/text/vertical/VerticalTextLayoutTest.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.text.TextPaint
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class VerticalTextLayoutTest {
+    // The detailed behavior tests are written in LineBreakerTests and underlying LayoutRunTests.
+    // In this test case, just check the set in builder and get in instance.
+
+    val PAINT =
+        TextPaint().apply() {
+            textSize = 10f // make 1em = 10px
+        }
+
+    val JP_TEXT = "吾輩は猫である。\n1904年(明治39年)生まれである。\n英名はI Am a Catである。"
+
+    @Test
+    fun `create default params`() {
+        VerticalTextLayout.Builder(JP_TEXT, 0, JP_TEXT.length, PAINT, 100f).build().run {
+            assertThat(text).isEqualTo(JP_TEXT)
+            assertThat(start).isEqualTo(0)
+            assertThat(end).isEqualTo(JP_TEXT.length)
+            assertThat(paint).isSameInstanceAs(PAINT)
+            assertThat(height).isEqualTo(100f)
+            assertThat(orientation).isEqualTo(TextOrientation.MIXED)
+        }
+    }
+
+    @Test
+    fun `create upright orientation`() {
+        VerticalTextLayout.Builder(JP_TEXT, 0, JP_TEXT.length, PAINT, 100f)
+            .setOrientation(TextOrientation.UPRIGHT)
+            .build()
+            .run {
+                assertThat(text).isEqualTo(JP_TEXT)
+                assertThat(start).isEqualTo(0)
+                assertThat(end).isEqualTo(JP_TEXT.length)
+                assertThat(paint).isSameInstanceAs(PAINT)
+                assertThat(height).isEqualTo(100f)
+                assertThat(orientation).isEqualTo(TextOrientation.UPRIGHT)
+            }
+    }
+}
diff --git a/text/text-vertical/src/main/java/androidx/text/vertical/LayoutRun.kt b/text/text-vertical/src/main/java/androidx/text/vertical/LayoutRun.kt
new file mode 100644
index 0000000..f9c49ea
--- /dev/null
+++ b/text/text-vertical/src/main/java/androidx/text/vertical/LayoutRun.kt
@@ -0,0 +1,490 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.Paint.FontMetrics
+import android.graphics.Paint.FontMetricsInt
+import android.text.Spanned
+import android.text.TextPaint
+import android.text.style.CharacterStyle
+import java.util.LinkedList
+import kotlin.concurrent.getOrSet
+import kotlin.math.max
+import kotlin.math.min
+
+// Constants for better readability.
+private const val HORIZONTAL = false
+private const val VERTICAL = true
+
+/**
+ * Creates a new LayoutRun instance.
+ *
+ * @param text The text to be laid out.
+ * @param start The inclusive starting index.
+ * @param end The exclusive ending index.
+ * @param paint The TextPaint object used to measure and draw the text.
+ * @param orientation The resolved orientation mode.
+ */
+internal fun createLayoutRun(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    paint: TextPaint,
+    orientation: ResolvedOrientation
+): LayoutRun =
+    when (orientation) {
+        ResolvedOrientation.Rotate -> RotateLayoutRun(text, start, end, paint)
+        ResolvedOrientation.Upright -> UprightLayoutRun(text, start, end, paint)
+        ResolvedOrientation.TateChuYoko -> TateChuYokoLayoutRun(text, start, end, paint)
+    }
+
+/**
+ * Represents a segment of text laid out with specific orientation and styling. This is an internal
+ * class used for managing text layout variations.
+ */
+internal sealed class LayoutRun(
+    val text: CharSequence,
+    val start: Int,
+    val end: Int,
+) {
+    /**
+     * Distance from left most position from the baseline in pixels.
+     *
+     * This is usually negative value.
+     *
+     * To get the next drawing horizontal coordinate, add this amount to the baseline. To get the
+     * width of this run, subtract this amount from the [rightSideOffset] value, i.e. width =
+     * right - left.
+     */
+    abstract val leftSideOffset: Float
+
+    /**
+     * Distance from right most position from the baseline in pixels.
+     *
+     * This is usually positive value.
+     *
+     * To get baseline of this run, subtract this amount from the drawing offset. To get the width
+     * of this run, subtract [leftSideOffset] from this amount, i.e. width = right - left.
+     */
+    abstract val rightSideOffset: Float
+
+    /**
+     * Distance from the top to bottom in pixels.
+     *
+     * This is always positive value.
+     */
+    abstract val height: Float
+
+    /**
+     * Distance from the right to left in pixels.
+     *
+     * This is always positive value.
+     */
+    val width
+        get() = rightSideOffset - leftSideOffset
+
+    /**
+     * Calculates the character advances and stores them in the `out` array.
+     *
+     * [out] must have at least [end - start] elements.
+     *
+     * @param out The array to store the character advances.
+     * @param paint The paint used for text rendering.
+     */
+    abstract fun getCharAdvances(out: FloatArray, paint: TextPaint)
+
+    /**
+     * Draws the laid out text on the canvas.
+     *
+     * @param canvas The canvas to draw on.
+     * @param originX The x-coordinate of the top-right corner of the text on the canvas.
+     * @param originY The y-coordinate of the top-right corner of the text on the canvas.
+     * @param paint The paint used for text rendering.
+     */
+    abstract fun draw(canvas: Canvas, originX: Float, originY: Float, paint: TextPaint)
+
+    /** Draws the background rectangle on the Canvas. */
+    protected fun drawBackground(
+        canvas: Canvas,
+        left: Float,
+        top: Float,
+        width: Float,
+        height: Float,
+        bgColor: Int
+    ) {
+        if (bgColor == 0) {
+            return
+        }
+        tempPaint { bgPaint ->
+            bgPaint.color = bgColor
+            canvas.drawRect(left, top, left + width, top + height, bgPaint)
+        }
+    }
+}
+
+/**
+ * Represents a "Tate-chu-yoko" (horizontal in vertical) text layout run.
+ *
+ * @param text The text this layout represents.
+ * @param start The starting inclusive index of the text.
+ * @param end The ending exclusive index of the text.
+ * @param paint The paint used for text rendering.
+ */
+internal class TateChuYokoLayoutRun(text: CharSequence, start: Int, end: Int, paint: TextPaint) :
+    LayoutRun(text, start, end) {
+    override val height: Float
+        get() = descent - ascent
+
+    override val leftSideOffset: Float
+    override val rightSideOffset: Float
+
+    /** The ascent of the tate-chu-yoko text. */
+    private val ascent: Float
+
+    /** The descent of the tate-chu-yoko text. */
+    private val descent: Float
+
+    /**
+     * The horizontal scaling factor applied to the text.
+     *
+     * If the text is too long to fit in the surrounding width, this factor will be used to shrink
+     * the text to fit in the given width.
+     */
+    private val scaleX: Float
+
+    /** The actual width occupied by the text. This is used for centering. */
+    private val textWidth: Float
+
+    init {
+        var leftSide = 0f
+        var rightSide = 0f
+        var maxAscent = 0
+        var maxDescent = 0
+
+        val fontMetrics = FontMetricsInt()
+
+        var textWidth = 0f
+        text.forStyleRuns(start, end, paint, HORIZONTAL) { rStart, rEnd, rPaint, _ ->
+            val rCount = rEnd - rStart
+
+            leftSide = min(leftSide, -rPaint.textSize * 0.5f)
+            rightSide = max(rightSide, rPaint.textSize * 0.5f)
+
+            rPaint.getFontMetricsInt(text, rStart, rCount, rStart, rCount, false, fontMetrics)
+            maxAscent = min(maxAscent, fontMetrics.ascent)
+            maxDescent = max(maxDescent, fontMetrics.descent)
+
+            textWidth += rPaint.measureText(text, rStart, rEnd)
+        }
+
+        val w = rightSide - leftSide
+        var scaleX = 1f
+        // Adjust the width and scaling if necessary to fit the text within the desired bounds.
+        if (textWidth > w) {
+            if (textWidth <= w * 1.1f) {
+                // If the text exceeds the width by up to 10%, expand the width by 10%.
+                leftSide *= 1.1f
+                rightSide *= 1.1f
+            } else {
+                // If the text exceeds the width significantly, shrink the text.
+                leftSide *= 1.1f
+                rightSide *= 1.1f
+                scaleX = 1.1f * w / textWidth
+                textWidth = 1.1f * w
+            }
+        }
+
+        this.descent = maxDescent.toFloat()
+        this.ascent = maxAscent.toFloat()
+        this.leftSideOffset = leftSide
+        this.rightSideOffset = rightSide
+        this.scaleX = scaleX
+        this.textWidth = textWidth
+    }
+
+    override fun draw(canvas: Canvas, originX: Float, originY: Float, paint: TextPaint) {
+        var x = originX + leftSideOffset + (width - textWidth) / 2 // centering
+        var y = originY - ascent
+        text.forStyleRuns(start, end, paint, HORIZONTAL) { rStart, rEnd, rPaint, bgColor ->
+            withTempScaleX(rPaint, scaleX) {
+                val w = rPaint.measureText(text, rStart, rEnd)
+                val h = descent - ascent
+
+                // Draw a background rectangle if a background color is specified.
+                drawBackground(canvas, x, y + ascent, w, h, bgColor)
+
+                canvas.drawText(text, rStart, rEnd, x, y, rPaint)
+
+                // Advance the draw offset for the next style.
+                x += w
+            }
+        }
+    }
+
+    override fun getCharAdvances(out: FloatArray, paint: TextPaint) {
+        // The line break won't happen inside Tate-chu-yoko span.
+        out[0] = height
+        if (out.size > 1) {
+            out.fill(0f, 1, out.size)
+        }
+    }
+}
+
+/**
+ * Represents a layout run that rotates the text by 90 degrees.
+ *
+ * @param text The text this layout represents.
+ * @param start The starting inclusive index of the text.
+ * @param end The ending exclusive index of the text.
+ * @param paint The paint used for text rendering.
+ */
+internal class RotateLayoutRun(text: CharSequence, start: Int, end: Int, paint: TextPaint) :
+    LayoutRun(text, start, end) {
+    override val height: Float
+    override val leftSideOffset: Float
+    override val rightSideOffset: Float
+    private val ascent: Float
+    private val descent: Float
+
+    init {
+        var height = 0f
+        var leftSide = 0f
+        var rightSide = 0f
+        var ascent = 0f
+        var descent = 0f
+
+        val metrics = FontMetrics()
+        text.forStyleRuns(start, end, paint, HORIZONTAL) { rStart, rEnd, rPaint, _ ->
+            height += rPaint.measureText(text, rStart, rEnd)
+            leftSide = min(leftSide, -rPaint.textSize * 0.5f)
+            rightSide = max(rightSide, rPaint.textSize * 0.5f)
+            rPaint.getFontMetrics(metrics)
+            ascent = min(ascent, metrics.ascent)
+            descent = max(descent, metrics.descent)
+        }
+
+        this.leftSideOffset = leftSide
+        this.rightSideOffset = rightSide
+        this.height = height
+        this.ascent = ascent
+        this.descent = descent
+    }
+
+    override fun draw(canvas: Canvas, originX: Float, originY: Float, paint: TextPaint) {
+        canvas.save()
+        try {
+            // To horizontal centering the rotated string, adjust the baseline offset.
+            canvas.translate(originX + (ascent + descent) * 0.5f, originY)
+            canvas.rotate(90f, 0f, 0f)
+
+            var x = 0f
+            text.forStyleRuns(start, end, paint, HORIZONTAL) { rStart, rEnd, rPaint, bgColor ->
+                val width = rPaint.measureText(text, rStart, rEnd)
+                drawBackground(canvas, x, ascent, width, descent - ascent, bgColor)
+                canvas.drawText(text, rStart, rEnd, x, 0f, rPaint)
+                x += width
+            }
+        } finally {
+            canvas.restore()
+        }
+    }
+
+    override fun getCharAdvances(out: FloatArray, paint: TextPaint) {
+        text.forStyleRuns(start, end, paint, HORIZONTAL) { rStart, rEnd, rPaint, _ ->
+            rPaint.getRunCharacterAdvance(
+                text,
+                rStart,
+                rEnd, // target range
+                rStart,
+                rEnd, // context range
+                false, // RTL // TODO: support RTL
+                rEnd, // offset,
+                out,
+                rStart - start
+            )
+        }
+    }
+}
+
+/**
+ * Represents an upright text layout run, where text is laid out vertically.
+ *
+ * @param text The text this layout represents.
+ * @param start The starting inclusive index of the text.
+ * @param end The ending exclusive index of the text.
+ * @param paint The paint used for text rendering.
+ */
+internal class UprightLayoutRun(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    paint: TextPaint,
+) : LayoutRun(text, start, end) {
+
+    override val height: Float
+    override val leftSideOffset: Float
+    override val rightSideOffset: Float
+
+    init {
+        var height = 0f
+        var left = 0f
+        var right = 0f
+
+        text.forStyleRuns(start, end, paint, VERTICAL) { rStart, rEnd, rPaint, _ ->
+            height += rPaint.measureText(text, rStart, rEnd)
+            left = min(left, -rPaint.textSize * 0.5f)
+            right = max(right, rPaint.textSize * 0.5f)
+        }
+        this.height = height
+        this.leftSideOffset = left
+        this.rightSideOffset = right
+    }
+
+    override fun draw(canvas: Canvas, originX: Float, originY: Float, paint: TextPaint) {
+        var y = originY
+        text.forStyleRuns(start, end, paint, VERTICAL) { rStart, rEnd, rPaint, bgColor ->
+            if (bgColor != 0) {
+                tempPaint { bgWorkPaint ->
+                    bgWorkPaint.color = bgColor
+                    canvas.drawRect(
+                        originX + leftSideOffset,
+                        y,
+                        originX + rightSideOffset,
+                        y + height,
+                        bgWorkPaint
+                    )
+                }
+            }
+
+            canvas.drawText(text, rStart, rEnd, originX, y, rPaint)
+            y += rPaint.measureText(text, rStart, rEnd)
+        }
+    }
+
+    override fun getCharAdvances(out: FloatArray, paint: TextPaint) {
+        text.forStyleRuns(start, end, paint, VERTICAL) { rStart, rEnd, rPaint, _ ->
+            rPaint.getRunCharacterAdvance(
+                text,
+                rStart,
+                rEnd, // target range
+                rStart,
+                rEnd, // context range
+                false, // RTL
+                rEnd, // offset,
+                out,
+                rStart - start
+            ) // out array and its index
+        }
+    }
+}
+
+/**
+ * Extension function to iterate over style runs within a CharSequence, applying specific styles and
+ * vertical orientation.
+ *
+ * @param start The inclusive start index of the range to process.
+ * @param end The exclusive end index of the range to process.
+ * @param basePaint The base paint to use for drawing.
+ * @param isVertical If true, sets the vertical text flag; otherwise, clears it.
+ */
+private inline fun CharSequence.forStyleRuns(
+    start: Int,
+    end: Int,
+    basePaint: TextPaint,
+    isVertical: Boolean,
+    crossinline block: (Int, Int, Paint, Int) -> Unit
+) {
+    // Easy case: if the text is a non-styled text, just call back entire text with applying
+    // vertical flag.
+    if (this !is Spanned) {
+        applyVerticalFlag(basePaint, isVertical) { block(start, end, it, 0 /* bgColor */) }
+        return
+    }
+
+    tempPaint { workPaint ->
+        var current = start
+        while (current < end) {
+            val rEnd = nextSpanTransition(current, end, CharacterStyle::class.java)
+            val styles = getSpans(current, rEnd, CharacterStyle::class.java)
+
+            workPaint.set(basePaint)
+            styles.forEach { it.updateDrawState(workPaint) }
+            applyVerticalFlag(workPaint, isVertical) {
+                block(current, rEnd, workPaint, workPaint.bgColor)
+            }
+            current = rEnd
+        }
+    }
+}
+
+/**
+ * Applies or removes the vertical text flag from the given Paint.
+ *
+ * @param paint The paint to modify.
+ * @param isVertical True to add the flag, false to remove it.
+ * @param block A lambda to execute with the modified paint.
+ */
+private inline fun applyVerticalFlag(
+    paint: Paint,
+    isVertical: Boolean,
+    crossinline block: (Paint) -> Unit
+) {
+    val originalFlags = paint.flags
+    paint.flags =
+        if (isVertical) {
+            paint.flags or Paint.VERTICAL_TEXT_FLAG
+        } else {
+            paint.flags and Paint.VERTICAL_TEXT_FLAG.inv()
+        }
+
+    try {
+        block(paint)
+    } finally {
+        paint.flags = originalFlags
+    }
+}
+
+private val paintPool = ThreadLocal<LinkedList<TextPaint>>()
+
+private inline fun tempPaint(crossinline block: (TextPaint) -> Unit) {
+    val pool = paintPool.getOrSet { LinkedList<TextPaint>() }
+    var paint = if (pool.isNotEmpty()) pool.remove() else TextPaint()
+    try {
+        block(paint)
+    } finally {
+        if (pool.size <= 2) { // Pool up to two paints.
+            pool.push(paint)
+        }
+    }
+}
+
+/** Executes a block of code with a temporary scaling X of the text size of a given [TextPaint]. */
+private inline fun <T : Paint, R> withTempScaleX(
+    textPaint: T,
+    scaleX: Float,
+    crossinline block: () -> R
+): R {
+    val originalScaleX = textPaint.textScaleX
+    textPaint.textScaleX = scaleX
+    try {
+        return block()
+    } finally {
+        textPaint.textScaleX = originalScaleX
+    }
+}
diff --git a/text/text-vertical/src/main/java/androidx/text/vertical/LineBreaker.kt b/text/text-vertical/src/main/java/androidx/text/vertical/LineBreaker.kt
new file mode 100644
index 0000000..53b6ca2
--- /dev/null
+++ b/text/text-vertical/src/main/java/androidx/text/vertical/LineBreaker.kt
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Canvas
+import android.text.TextPaint
+import androidx.annotation.Px
+import androidx.text.vertical.LineBreaker.Result
+import java.text.BreakIterator
+import java.util.Locale
+import kotlin.math.max
+import kotlin.math.min
+
+// Illustrate meaning of baseline, left, right and drawing offset.
+// (Vertical LR case, line grows from right to left.)
+//
+//         2nd line            1st line
+//
+//           width               width
+//    <---------------->   <---------------->
+//    leftSide  rightSide   leftSide rightSide
+//    <-------- ------->   <-------- ------->
+//       2nd baseline        1st baseline
+//   |         |         |         |         +Drawing offset (top-right corner)
+//   |  +------+------+  |  +------+------+  |
+//   |  |      |      |  |  |      |      |  |
+//   |  |  n-th char  |  |  |   1st char  |  |
+//   |  |      |      |  |  |      |      |  |
+//   |  |      |      |  |  |      |      |  |
+//   |  +------+------+  |  +------+------+  |
+//   |  |      |      |  |  |      |      |  |
+//   |  | n+1-th char |  |  |   2nd char  |  |
+//   |  |      |      |  |  |      |      |  |
+//   |  |      |      |  |  |      |      |  |
+//   |  +------+------+  |  +------+------+  |
+//   |  |      |      |  |  |      |      |  |
+//   |  |      |      |  |  |      |      |  |
+//   |  |      |      |  |  |      |      |  |
+//                          ^1st line left   ^1st line right
+//   ^2nd line left   ^2nd line right
+//
+// The rightSide is a positive distance from the baseline to the line right.
+//
+// The leftSide is a negative distance from the baseline to the line left.
+//
+// The width is a positive distance from the line left to line right.
+// The width is calculated with right - left.
+
+internal object LineBreaker {
+    /**
+     * Represents lines of text that has been laid out.
+     *
+     * @property width The total width of the line.
+     * @property lineLeftSide The distance from each line left to each line baseline.
+     * @property lineRightSide The distance from each line baseline to each line right.
+     */
+    class Result(
+        private val lineLayouts: List<LineLayout>,
+        val width: Float,
+        val lineLeftSide: Float,
+        val lineRightSide: Float
+    ) {
+        /** The number of lines in the text layout. */
+        val lineCount: Int
+            get() = lineLayouts.size
+
+        /**
+         * Retrieves the inclusive starting character index of a specified line.
+         *
+         * @param lineNo The line number.
+         * @return The inclusive starting character index of the specified line.
+         */
+        fun getLineStart(lineNo: Int) = lineLayouts[lineNo].start
+
+        /**
+         * Retrieves the exclusive ending character index of a specified line.
+         *
+         * @param lineNo The line number.
+         * @return The exclusive ending character index of the specified line.
+         */
+        fun getLineEnd(lineNo: Int) = lineLayouts[lineNo].end
+
+        /**
+         * Draws the text lines onto the given canvas.
+         *
+         * @param canvas The Canvas to draw on.
+         * @param x The starting X position for drawing. The right-top is the drawing origin.
+         * @param y The starting Y position for drawing. The right-top is the drawing origin.
+         * @param paint The TextPaint object to use for text rendering.
+         */
+        fun draw(canvas: Canvas, x: Float, y: Float, paint: TextPaint) {
+            val lineWidth = lineRightSide - lineLeftSide
+            lineLayouts.forEachIndexed { i, line ->
+                // Baseline offset of the i-th line.
+                val baselineOffset = -lineWidth * i - lineRightSide
+                line.draw(canvas, x + baselineOffset, y, paint)
+            }
+        }
+    }
+
+    /**
+     * Performs a line break and layouts each lines.
+     *
+     * @param text The text to be processed.
+     * @param start The inclusive starting index of the range.
+     * @param end The exclusive ending index of the range.
+     * @param paint The TextPaint used for measuring and drawing text.
+     * @param heightConstraint The height constraint in pixels.
+     * @param textOrientation The desired orientation for the text (MIXED, HORIZONTAL, VERTICAL).
+     *   Defaults to MIXED.
+     * @return A Result object containing the broken text lines.
+     */
+    fun breakTextIntoLines(
+        text: CharSequence,
+        start: Int,
+        end: Int,
+        paint: TextPaint,
+        @Px heightConstraint: Float,
+        textOrientation: Int = TextOrientation.MIXED,
+    ): Result {
+        val ctx = Context(text, paint, heightConstraint)
+        text.forEachParagraph(start, end) { paraStart, paraEnd ->
+            forEachRubySpanTransition(text, paraStart, paraEnd) { runStart, runEnd, rubySpan ->
+                if (rubySpan == null) {
+                    forEachOrientation(text, runStart, runEnd, textOrientation) { oStart, oEnd, o ->
+                        if (o == ResolvedOrientation.TateChuYoko) {
+                            ctx.processTateChuYoko(oStart, oEnd)
+                        } else {
+                            ctx.processRun(oStart, oEnd, o)
+                        }
+                    }
+                } else {
+                    ctx.processRubyRun(runStart, runEnd, rubySpan, textOrientation)
+                }
+            }
+
+            // Add a line break after each paragraph except the last one.
+            if (paraEnd != end) {
+                ctx.breakLine()
+            }
+        }
+        return ctx.finish()
+    }
+}
+
+/**
+ * A custom word breaker for the line breaking specialized for vertical text.
+ *
+ * @property text The text to break into words.
+ * @property locale The locale for language-specific word breaking rules.
+ */
+private data class WordBreaker(val text: CharSequence, val locale: Locale) {
+    private var currentRunStart = -1 // unused init value
+    private var currentRunEnd = -1 // unused init value
+    private var currentRunOrientation = ResolvedOrientation.Upright // unused init value
+    private var currentHead = -1 // unused init value
+
+    val current: Int
+        get() = currentHead
+
+    private val br =
+        BreakIterator.getLineInstance(locale).apply {
+            // TODO: Introduce CharacterIterator
+            setText(this@WordBreaker.text.toString())
+        }
+
+    fun updateForRun(start: Int, end: Int, orientation: ResolvedOrientation) {
+        currentRunStart = start
+        currentRunEnd = end
+        currentRunOrientation = orientation
+        currentHead = currentRunStart
+        advanceBreakOffset()
+    }
+
+    /**
+     * Advances the word break offset within the current run.
+     *
+     * @return The new break offset.
+     */
+    fun advanceBreakOffset(): Int {
+        currentHead =
+            when (currentRunOrientation) {
+                ResolvedOrientation.Rotate -> br.following(currentHead)
+                ResolvedOrientation.Upright -> br.following(currentHead)
+                else -> throw RuntimeException("TateChuYoko and Ruby should not be broken.")
+            }
+        if (currentHead == BreakIterator.DONE || currentHead > currentRunEnd) {
+            currentHead = currentRunEnd
+        }
+        return currentHead
+    }
+}
+
+/**
+ * Manages the state and logic for breaking text into lines.
+ *
+ * @property text The input text.
+ * @property paint The paint used for measuring text.
+ * @property heightConstraint The height constraint.
+ */
+private data class Context(
+    val text: CharSequence,
+    val paint: TextPaint,
+    @Px val heightConstraint: Float,
+) {
+    val breaker = WordBreaker(text, paint.textLocale)
+    var currentLineHeight: Float = 0f
+    val currentLineRuns: MutableList<LayoutRun> = mutableListOf()
+    val brokenLines: MutableList<LineLayout> = mutableListOf()
+
+    /**
+     * Breaks the current line and adds it to the list of broken lines.
+     *
+     * This method also resets the current line context.
+     */
+    fun breakLine() {
+        require(currentLineRuns.isNotEmpty()) { "Cannot break with empty runs." }
+        brokenLines.add(LineLayout(currentLineRuns.toList()))
+        currentLineRuns.clear()
+        currentLineHeight = 0f
+    }
+
+    private fun addRun(start: Int, end: Int, orientation: ResolvedOrientation) =
+        currentLineRuns.add(createLayoutRun(text, start, end, paint, orientation))
+
+    /**
+     * Iterate through each words within a specified range of a CharSequence.
+     *
+     * @param start The inclusive starting index of the range.
+     * @param end The exclusive ending index of the range.
+     * @param advances An array advances.
+     * @param consumer A callback function that is called for each words. It receives three
+     *   parameters:
+     *     - The inclusive start index of the word.
+     *     - The exclusive end index of the word.
+     *     - The height of the word.
+     */
+    private inline fun forEachWord(
+        start: Int,
+        end: Int,
+        orientation: ResolvedOrientation,
+        advances: FloatArray,
+        crossinline consumer: (Int, Int, Float) -> Unit
+    ) {
+        breaker.updateForRun(start, end, orientation)
+
+        var wordStart = start
+        var wordHeight = 0f
+        for (i in start until end) {
+            wordHeight += advances[i - start]
+            if (i + 1 == breaker.current) {
+                consumer(wordStart, i + 1, wordHeight)
+
+                wordStart = i + 1
+                wordHeight = 0f
+                breaker.advanceBreakOffset()
+            }
+        }
+    }
+
+    private inline fun forEachGrapheme(
+        wStart: Int,
+        wEnd: Int,
+        advances: FloatArray,
+        advancesOffset: Int,
+        crossinline consumer: (Int, Int, Float) -> Unit
+    ) {
+        var gStart = wStart
+        for (i in wStart + 1 until wEnd) {
+            if (advances[i - advancesOffset] == 0.0f) {
+                // If multiple characters are assigned to the single grapheme, the advance is
+                // assigned to the first character and remaining are zeros. Therefore, call the
+                // consumer with the first character offset and last character offset that has zero
+                // advance.
+                continue
+            }
+
+            consumer(gStart, i, advances[gStart - advancesOffset])
+            gStart = i
+        }
+        consumer(gStart, wEnd, advances[gStart - advancesOffset])
+    }
+
+    /**
+     * Processes breakable continued run.
+     *
+     * For TateChuYoko, use processTateChuYokoRun, for Ruby, use processRubyRun
+     *
+     * @param start The inclusive starting index of the run.
+     * @param end The exclusive ending index of the run.
+     * @param orientation The text orientation of the run (e.g., Horizontal, Vertical, TateChuYoko).
+     */
+    fun processRun(start: Int, end: Int, orientation: ResolvedOrientation) {
+        require(
+            orientation == ResolvedOrientation.Upright || orientation == ResolvedOrientation.Rotate
+        )
+        breaker.updateForRun(start, end, orientation)
+
+        val advances = FloatArray(end - start)
+        val layout = createLayoutRun(text, start, end, paint, orientation)
+        layout.getCharAdvances(advances, paint)
+
+        var lineStartOffset = start
+        var lastKnownGoodBreakOffset = -1
+        forEachWord(start, end, orientation, advances) { wStart, wEnd, wHeight ->
+            if (currentLineHeight + wHeight <= heightConstraint) {
+                // We still have space. Just update the line height.
+                currentLineHeight += wHeight
+                lastKnownGoodBreakOffset = wEnd
+                return@forEachWord
+            }
+
+            // Okay, the current word cannot fit the line. If we know the previous offset, break
+            // with it.
+            if (lastKnownGoodBreakOffset != -1) {
+                // If there is a good break offset before, break with it.
+                addRun(lineStartOffset, lastKnownGoodBreakOffset, orientation)
+                breakLine()
+
+                lineStartOffset = wStart
+                lastKnownGoodBreakOffset = -1
+            } else if (currentLineRuns.isNotEmpty()) {
+                // If this is the first break offset, and if some runs are already in the current
+                // line, break here (the beginning of the run) first.
+                breakLine()
+
+                lineStartOffset = wStart
+                lastKnownGoodBreakOffset = -1
+            }
+
+            // As the result of line break, if the current word can fit in the line,
+            // keep continue to the next word.
+            if (wHeight <= heightConstraint) {
+                currentLineHeight = wHeight
+                lastKnownGoodBreakOffset = wEnd
+                return@forEachWord
+            }
+
+            // Oh no, we don't have any break offset before this offset.
+            // Try to break text with desperate break.
+
+            // First, give up for TateChuYoko orientations cannot be broken further.
+            if (orientation == ResolvedOrientation.TateChuYoko) {
+                addRun(wStart, wEnd, orientation)
+                breakLine()
+                lineStartOffset = wEnd
+                return@forEachWord
+            }
+
+            forEachGrapheme(lineStartOffset, wEnd, advances, start) { gStart, gEnd, gHeight ->
+                if (gStart == lineStartOffset) {
+                    // Ensure there's at least one grapheme per line during breaking.
+                    currentLineHeight = gHeight
+                    lastKnownGoodBreakOffset = gEnd
+                    return@forEachGrapheme
+                } else if (currentLineHeight + gHeight <= heightConstraint) {
+                    // We still have space. Extend the current line and continues
+                    currentLineHeight += gHeight
+                    lastKnownGoodBreakOffset = gEnd
+                    return@forEachGrapheme
+                }
+
+                // We don't have space, so break line with the previously known good grapheme break
+                // offset.
+                addRun(lineStartOffset, lastKnownGoodBreakOffset, orientation)
+                breakLine()
+
+                // Updating the current line but ensure there's at least one grapheme per line.
+                currentLineHeight = gHeight
+                lineStartOffset = lastKnownGoodBreakOffset
+                lastKnownGoodBreakOffset = gEnd
+            }
+        }
+
+        // Add the remaining part of the run to the current line.
+        addRun(lineStartOffset, end, orientation)
+    }
+
+    /**
+     * Processes a continued text run within a layout for RubySpan.
+     *
+     * @param start The inclusive starting index of the run.
+     * @param end The exclusive ending index of the run.
+     * @param ruby The ruby span.
+     * @param orientation The text orientation mode.
+     */
+    fun processRubyRun(start: Int, end: Int, ruby: RubySpan, @OrientationMode orientation: Int) {
+        val rubyLayout = RubyLayoutRun(text, start, end, orientation, paint, ruby)
+        processNonBreakableLayout(rubyLayout)
+    }
+
+    fun processTateChuYoko(start: Int, end: Int) {
+        val layout = createLayoutRun(text, start, end, paint, ResolvedOrientation.TateChuYoko)
+        processNonBreakableLayout(layout)
+    }
+
+    private fun processNonBreakableLayout(layout: LayoutRun) {
+        val height = layout.height
+        if (currentLineHeight + height <= heightConstraint) {
+            currentLineRuns.add(layout)
+            currentLineHeight += height
+            return
+        }
+
+        if (currentLineRuns.isNotEmpty()) {
+            // The line goes over the height limit by appending this Layout.
+            // Break it before adding Ruby.
+            breakLine()
+        }
+
+        if (height <= heightConstraint) {
+            currentLineRuns.add(layout)
+            currentLineHeight = height
+            return
+        }
+
+        currentLineRuns.add(layout)
+        breakLine()
+    }
+
+    /**
+     * Finishes the line breaking process and returns the result.
+     *
+     * @return The result of the line breaking process.
+     */
+    fun finish(): Result {
+        breakLine()
+
+        // To use the same line width, iterate over all lines and use the maximum of it.
+        var leftSide = 0f
+        var rightSide = 0f
+
+        brokenLines.forEach {
+            leftSide = min(leftSide, it.leftSide)
+            rightSide = max(rightSide, it.rightSide)
+        }
+
+        return Result(brokenLines, (rightSide - leftSide) * brokenLines.size, leftSide, rightSide)
+    }
+}
diff --git a/text/text-vertical/src/main/java/androidx/text/vertical/LineLayout.kt b/text/text-vertical/src/main/java/androidx/text/vertical/LineLayout.kt
new file mode 100644
index 0000000..c26c9ed
--- /dev/null
+++ b/text/text-vertical/src/main/java/androidx/text/vertical/LineLayout.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Canvas
+import android.text.TextPaint
+import kotlin.math.max
+import kotlin.math.min
+
+/**
+ * Creates a LineLayout.
+ *
+ * @param text The text to be laid out.
+ * @param start The inclusive starting index.
+ * @param end The exclusive ending index.
+ * @param paint The TextPaint object used to measure and draw the text.
+ * @param textOrientation The orientation mode.
+ */
+internal fun createLineLayout(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    paint: TextPaint,
+    @OrientationMode textOrientation: Int
+) =
+    LineLayout(
+        mutableListOf<LayoutRun>().apply {
+            forEachOrientation(text, start, end, textOrientation) { runStart, runEnd, orientation ->
+                add(createLayoutRun(text, runStart, runEnd, paint, orientation))
+            }
+        }
+    )
+
+/**
+ * Represents a layout of multiple [LayoutRun]s arranged in a single line.
+ *
+ * @param runs The list of [LayoutRun]s composing this layout.
+ */
+internal class LineLayout(
+    val runs: List<LayoutRun>,
+) {
+    val start: Int
+        get() = runs.first().start
+
+    val end: Int
+        get() = runs.last().end
+
+    /**
+     * Distance from left most position from the baseline in pixels.
+     *
+     * This is usually negative value.
+     *
+     * To get the next drawing horizontal coordinate, add this amount to the baseline. To get the
+     * width of this run, subtract this amount from the [rightSide] value, i.e. width = right -
+     * left.
+     */
+    val leftSide: Float
+
+    /**
+     * Distance from right most position from the baseline in pixels.
+     *
+     * This is usually positive value.
+     *
+     * To get baseline of this run, subtract this amount from the drawing offset. To get the width
+     * of this run, subtract [leftSide] from this amount, i.e. width = right - left.
+     */
+    val rightSide: Float
+
+    /**
+     * Distance from the top to bottom in pixels.
+     *
+     * This is always positive value.
+     */
+    val height: Float
+
+    /**
+     * Distance from the right to left in pixels.
+     *
+     * This is always positive value.
+     */
+    val width: Float
+        get() = rightSide - leftSide
+
+    init {
+        val (l, r, h) =
+            runs.fold(Triple(0f, 0f, 0f)) { acc, run ->
+                Triple(
+                    min(acc.first, run.leftSideOffset), // leftSide
+                    max(acc.second, run.rightSideOffset), // rightSide
+                    acc.third + run.height // height
+                )
+            }
+        leftSide = l
+        rightSide = r
+        height = h
+    }
+
+    /**
+     * Draws the laid out text on the canvas as a single line.
+     *
+     * @param canvas The canvas to draw on.
+     * @param originX The x-coordinate of the drawing origin.
+     * @param originY The y-coordinate of the drawing origin.
+     * @param paint The paint used for text rendering.
+     */
+    fun draw(canvas: Canvas, originX: Float, originY: Float, paint: TextPaint) {
+        var y = originY
+        runs.forEach { run ->
+            run.draw(canvas, originX, y, paint)
+            y += run.height
+        }
+    }
+}
diff --git a/text/text-vertical/src/main/java/androidx/text/vertical/Orientations.kt b/text/text-vertical/src/main/java/androidx/text/vertical/Orientations.kt
new file mode 100644
index 0000000..6771e4d
--- /dev/null
+++ b/text/text-vertical/src/main/java/androidx/text/vertical/Orientations.kt
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.icu.lang.UCharacter
+import android.icu.lang.UCharacter.VerticalOrientation
+import android.icu.lang.UProperty
+import android.text.Spanned
+import androidx.annotation.IntDef
+
+/**
+ * Represents the orientation of text within a vertical writing mode.
+ *
+ * This controls how text characters are displayed when using a vertical writing mode. For more
+ * information, refer to:
+ * [CSS text-orientation](https://www.w3.org/TR/css-writing-modes-3/#text-orientation)
+ */
+public object TextOrientation {
+    /**
+     * Characters from horizontal scripts are rotated 90 degrees clockwise, while characters from
+     * vertical scripts remain in their original orientation.
+     *
+     * This is useful for mixed-script content where you want horizontal text to fit vertically
+     * while vertical text remains upright.
+     *
+     * Corresponds to CSS `text-orientation: mixed;`.
+     */
+    public const val MIXED: Int = 0
+
+    /**
+     * A value for the text orientation that represents the text will be laid out with the original
+     * orientations.
+     */
+    /**
+     * All characters are laid out in upright orientation, regardless of script.
+     *
+     * This is useful when you want all characters to remain upright even for horizontal scripts.
+     *
+     * Corresponds to CSS `text-orientation: upright;`.
+     */
+    public const val UPRIGHT: Int = 1
+
+    /**
+     * All characters are rotated 90 degrees clockwise, regardless of script.
+     *
+     * This is useful when you want all text to be sideways in a vertical layout.
+     *
+     * Corresponds to CSS `text-orientation: sideways;`.
+     */
+    public const val SIDEWAYS: Int = 2
+}
+
+@IntDef(value = [TextOrientation.MIXED, TextOrientation.UPRIGHT, TextOrientation.SIDEWAYS])
+internal annotation class OrientationMode
+
+/**
+ * A sealed interface representing text orientation spans for use within a vertical text layout.
+ *
+ * These spans allow for overriding the default text orientation of portions of text, such as
+ * setting it to upright, sideways, or combining text horizontally within a vertical flow
+ * (tate-chu-yoko).
+ *
+ * These spans are intended for use with [VerticalTextLayout].
+ */
+public sealed interface TextOrientationSpan {
+    /**
+     * A span that forces the enclosed text to be displayed in an upright orientation
+     * ([TextOrientation.UPRIGHT]) within a vertical text layout.
+     *
+     * This is useful for ensuring that text remains vertical, even if the surrounding text flow is
+     * sideways.
+     *
+     * @see TextOrientation.UPRIGHT
+     * @see VerticalTextLayout
+     */
+    public class Upright : TextOrientationSpan
+
+    /**
+     * A span that forces the enclosed text to be displayed in a sideways orientation
+     * ([TextOrientation.SIDEWAYS]) within a vertical text layout.
+     *
+     * This is useful for orienting text horizontally when the surrounding text is vertical.
+     *
+     * @see TextOrientation.SIDEWAYS
+     * @see VerticalTextLayout
+     */
+    public class Sideways : TextOrientationSpan
+
+    /**
+     * A span that combines a small sequence of characters (typically 2-4 digits) into a single
+     * horizontal block within a vertical text flow.
+     *
+     * This is known as "tate-chu-yoko" in Japanese typography.
+     *
+     * @see VerticalTextLayout
+     */
+    public class TextCombineUpright() : TextOrientationSpan
+}
+
+/** Represents the resolved orientation of a run of text. */
+internal enum class ResolvedOrientation {
+    Upright,
+    Rotate,
+    TateChuYoko
+}
+
+/**
+ * `RunMerger` is a utility class designed to identify and merge consecutive runs of characters with
+ * the same orientation.
+ */
+private class RunMerger(val end: Int, val consumer: (Int, Int, ResolvedOrientation) -> Unit) {
+    private var prevStart = -1
+    private var prevOrientation = ResolvedOrientation.Upright
+
+    /**
+     * Appends a new segment to the current run.
+     *
+     * @param start The inclusive starting position of the segment to be appended.
+     * @param orientation The orientation of the current segment.
+     */
+    fun append(start: Int, orientation: ResolvedOrientation) {
+        if (prevStart == -1) {
+            prevStart = start
+            prevOrientation = orientation
+            return
+        } else if (
+            prevOrientation != orientation || orientation == ResolvedOrientation.TateChuYoko
+        ) {
+            // orientation transition point. callback and update the state
+            consumer(prevStart, start, prevOrientation)
+            prevStart = start
+            prevOrientation = orientation
+        } else {
+            // do nothing. keep extending the current run.
+        }
+    }
+
+    /** Finalize the merge and callback the last run. Do not call this method multiple times. */
+    fun finish() {
+        if (prevStart != -1) {
+            consumer(prevStart, end, prevOrientation)
+        }
+    }
+}
+
+/**
+ * Iterates over characters and resolves the each character's orientation property along with the
+ * attached `OrientationSpan`.
+ *
+ * @param text The CharSequence
+ * @param start The inclusive starting index
+ * @param end The exclusive ending index
+ * @param textOrientation The text orientation mode.
+ * @param consumer A callback function that is called for each orientation transition. It receives
+ *   three parameters:
+ *     - The inclusive start index of the orientation run.
+ *     - The exclusive end index of the orientation run.
+ *     - The orientation of the range.
+ */
+internal fun forEachOrientation(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    @OrientationMode textOrientation: Int,
+    consumer: (Int, Int, ResolvedOrientation) -> Unit
+) {
+    if (start >= end) {
+        return
+    }
+
+    if (text !is Spanned) {
+        // Easy case, no spans are attached.
+        forOrientationNoSpans(text, start, end, textOrientation, consumer)
+        return
+    }
+
+    val merger = RunMerger(end, consumer)
+    forEachSpan<TextOrientationSpan>(text, start, end) { runStart, runEnd, spans ->
+        if (spans.isEmpty()) {
+            forOrientationNoSpans(text, runStart, runEnd, textOrientation) { oStart, _, resolved ->
+                merger.append(oStart, resolved)
+            }
+        } else {
+            // If multiple TextOrientationSpans are attached, use the last one.
+            val resolved =
+                when (spans.last()) {
+                    is TextOrientationSpan.TextCombineUpright -> ResolvedOrientation.TateChuYoko
+                    is TextOrientationSpan.Upright -> ResolvedOrientation.Upright
+                    is TextOrientationSpan.Sideways -> ResolvedOrientation.Rotate
+                }
+            merger.append(runStart, resolved)
+        }
+    }
+    merger.finish()
+}
+
+/** Iterates over characters and resolves the each character's orientation property. */
+private inline fun forOrientationNoSpans(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    @OrientationMode textOrientation: Int,
+    crossinline consumer: (Int, Int, ResolvedOrientation) -> Unit
+) {
+    var prevProp = ResolvedOrientation.Upright // unused initial value
+    var prevStart = start
+    fotEachCodePoints(text, start, end) { i, cp ->
+        val prop = resolveOrientation(textOrientation, cp)
+        if (i == start) {
+            prevProp = prop
+        } else if (prevProp != prop) {
+            consumer(prevStart, i, prevProp)
+            prevProp = prop
+            prevStart = i
+        }
+    }
+    consumer(prevStart, end, prevProp)
+}
+
+/**
+ * Resolves the orientation of a character based on the provided text orientation and the
+ * character's code point.
+ *
+ * @param textOrientation The text orientation mode.
+ * @param cp The code point of the character.
+ * @return The resolved orientation of the character.
+ */
+private fun resolveOrientation(@OrientationMode textOrientation: Int, cp: Int) =
+    when (textOrientation) {
+        TextOrientation.UPRIGHT -> ResolvedOrientation.Upright
+        TextOrientation.SIDEWAYS -> ResolvedOrientation.Rotate
+        TextOrientation.MIXED -> {
+            when (UCharacter.getIntPropertyValue(cp, UProperty.VERTICAL_ORIENTATION)) {
+                VerticalOrientation.ROTATED -> ResolvedOrientation.Rotate
+                else -> ResolvedOrientation.Upright
+            }
+        }
+        else -> throw RuntimeException("Unknown orientation: $textOrientation")
+    }
diff --git a/text/text-vertical/src/main/java/androidx/text/vertical/Ruby.kt b/text/text-vertical/src/main/java/androidx/text/vertical/Ruby.kt
new file mode 100644
index 0000000..24b0303
--- /dev/null
+++ b/text/text-vertical/src/main/java/androidx/text/vertical/Ruby.kt
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.text.Spanned
+import android.text.TextPaint
+import kotlin.math.max
+
+/**
+ * A span used to specify ruby text for a portion of the text.
+ *
+ * Ruby text cannot be nested (i.e., ruby text cannot contain further ruby text). Ruby spans also
+ * cannot overlap each other.
+ *
+ * This span is designed for use with [VerticalTextLayout].
+ *
+ * @property text The ruby text to be displayed adjacent to the base text.
+ * @property orientation The text orientation of the ruby text. Defaults to [TextOrientation.MIXED].
+ * @property textScale The text scale ratio of the ruby text relative to the base text. Defaults to
+ *   0.5f.
+ */
+public class RubySpan
+private constructor(
+    public val text: CharSequence,
+    @OrientationMode public val orientation: Int,
+    public val textScale: Float,
+) {
+    /**
+     * Builder class for creating [RubySpan] instances.
+     *
+     * @param text The ruby text to be displayed adjacent to the base text.
+     */
+    public class Builder(private val text: CharSequence) {
+        private var _orientation: Int = TextOrientation.MIXED
+        private var _textScale: Float = 0.5f
+
+        /**
+         * Sets the text orientation for the ruby text.
+         *
+         * By default, [TextOrientation.MIXED] is used.
+         *
+         * @param orientation The text orientation to set.
+         * @return This [Builder] instance for method chaining.
+         */
+        public fun setOrientation(@OrientationMode orientation: Int): Builder = apply {
+            _orientation = orientation
+        }
+
+        /**
+         * Sets the text scale for the ruby text.
+         *
+         * By default, 0.5f is used, meaning the ruby text will be half the size of the base text.
+         *
+         * @param textScale The text scale to set.
+         * @return This [Builder] instance for method chaining.
+         */
+        public fun setTextScale(textScale: Float): Builder = apply { _textScale = textScale }
+
+        /**
+         * Builds and returns a new [RubySpan] instance.
+         *
+         * @return A new [RubySpan] instance.
+         */
+        public fun build(): RubySpan = RubySpan(text, _orientation, _textScale)
+    }
+}
+
+/**
+ * Iterates through each RubySpan within a specified range of a CharSequence.
+ *
+ * @param text The CharSequence
+ * @param start The inclusive starting index
+ * @param end The exclusive ending index
+ * @param consumer A callback function that is called for each RubySpan transition. It receives
+ *   three parameters:
+ *     - The inclusive start index of the RubySpan.
+ *     - The exclusive end index of the RubySpan.
+ *     - The `RubySpan` object itself, or `null` if no RubySpan is found.
+ */
+internal inline fun forEachRubySpanTransition(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    crossinline consumer: (Int, Int, RubySpan?) -> Unit
+) =
+    forEachSpan(text, start, end) { rStart, rEnd, rubySpans ->
+        require(rubySpans.size <= 1) { "RubySpan cannot be overlapped" }
+        consumer(rStart, rEnd, rubySpans.getOrNull(0))
+    }
+
+/**
+ * A special LayoutRun specialized for a Ruby text.
+ *
+ * @param text The text this layout represents.
+ * @param start The starting inclusive index of the text.
+ * @param end The ending exclusive index of the text.
+ * @param textOrientation The text orientation mode.
+ * @param paint The paint used for text rendering.
+ * @param rubySpan The rubySpan attached to the range.
+ */
+internal class RubyLayoutRun(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    @OrientationMode textOrientation: Int,
+    paint: TextPaint,
+    rubySpan: RubySpan,
+) : LayoutRun(text, start, end) {
+
+    init {
+        val rubyText = rubySpan.text
+        if (rubyText is Spanned) {
+            require(rubyText.getSpans(0, rubyText.length, RubySpan::class.java).isEmpty()) {
+                "Ruby text cannot have RubySpan. (Ruby cannot be nested.)"
+            }
+        }
+    }
+
+    override val height: Float
+        get() = max(bodyLayoutRuns.height, rubyLayoutRuns.height)
+
+    override val leftSideOffset: Float
+        get() = bodyLayoutRuns.leftSide
+
+    override val rightSideOffset: Float
+        get() = bodyLayoutRuns.rightSide + rubyLayoutRuns.width
+
+    private val rubyScale = rubySpan.textScale
+    private val rubyLayoutRuns: LineLayout =
+        withTempScale(paint, rubyScale) {
+            createLineLayout(rubySpan.text, 0, rubySpan.text.length, paint, rubySpan.orientation)
+        }
+    private val bodyLayoutRuns: LineLayout =
+        createLineLayout(text, start, end, paint, textOrientation)
+
+    override fun draw(canvas: Canvas, originX: Float, originY: Float, paint: TextPaint) {
+        val bodyHeight = bodyLayoutRuns.height
+        val rubyHeight = rubyLayoutRuns.height
+
+        // Vertical centering the body text and ruby text.
+        var bodyY = originY
+        var rubyY = originY
+        val heightDiffHalf = (bodyHeight - rubyHeight) / 2
+        if (heightDiffHalf > 0) {
+            // The body text is taller than the ruby text. Push the ruby text for centering.
+            rubyY += heightDiffHalf
+        } else {
+            // The body text is shorter than the ruby text. Push the body text for centering.
+            bodyY -= heightDiffHalf
+        }
+
+        bodyLayoutRuns.draw(canvas, originX, bodyY, paint)
+
+        val rubyX = originX + bodyLayoutRuns.rightSide - rubyLayoutRuns.leftSide
+        withTempScale(paint, rubyScale) { rubyLayoutRuns.draw(canvas, rubyX, rubyY, paint) }
+    }
+
+    override fun getCharAdvances(out: FloatArray, paint: TextPaint) {
+        // We don't support line break inside Ruby. Just assigning all height into the first
+        // character for preventing line break.
+        out[0] = height
+        if (out.size > 1) {
+            out.fill(0f, 1, out.size)
+        }
+    }
+}
+
+/**
+ * Executes a block of code with a temporary applying scaling of the text size of a given
+ * [TextPaint].
+ */
+private inline fun <T : Paint, R> withTempScale(
+    textPaint: T,
+    scale: Float,
+    crossinline block: () -> R
+): R {
+    val originalSize = textPaint.textSize
+    textPaint.textSize *= scale
+    try {
+        return block()
+    } finally {
+        textPaint.textSize = originalSize
+    }
+}
diff --git a/text/text-vertical/src/main/java/androidx/text/vertical/TextUtils.kt b/text/text-vertical/src/main/java/androidx/text/vertical/TextUtils.kt
new file mode 100644
index 0000000..a2845e2
--- /dev/null
+++ b/text/text-vertical/src/main/java/androidx/text/vertical/TextUtils.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.text.Spanned
+
+/**
+ * Iterates through spans of a specific type within a given range of a CharSequence.
+ *
+ * @param text The CharSequence
+ * @param start The inclusive starting index.
+ * @param end The exclusive ending index.
+ * @param consumer A lambda function that will be called for each segment containing spans.
+ */
+internal inline fun <reified T> forEachSpan(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    crossinline consumer: (Int, Int, Array<T>) -> Unit
+) {
+    if (text !is Spanned) {
+        consumer(start, end, arrayOf())
+        return
+    }
+
+    var spanI = start
+    while (spanI < end) {
+        val next = text.nextSpanTransition(spanI, end, T::class.java)
+        val spans = text.getSpans(spanI, next, T::class.java)
+        consumer(spanI, next, spans)
+        spanI = next
+    }
+}
+
+/**
+ * Iterates over the code points within a specified range of a [CharSequence].
+ *
+ * @param text The CharSequence
+ * @param start The inclusive starting index.
+ * @param end The exclusive ending index.
+ * @param consumer A lambda function that will be called for each code points.
+ */
+internal inline fun fotEachCodePoints(
+    text: CharSequence,
+    start: Int,
+    end: Int,
+    crossinline consumer: (Int, Int) -> Unit
+) {
+    var i = start
+    while (i < end) {
+        val cp = Character.codePointAt(text, i)
+        consumer(i, cp)
+        i += Character.charCount(cp)
+    }
+}
+
+/**
+ * Extension function to iterate over paragraphs within a CharSequence.
+ *
+ * This function iterates through the specified range of the CharSequence, identifying paragraphs
+ * based on newline characters ('\n'). For each paragraph found, it invokes the provided block with
+ * the start and end indices of the paragraph.
+ *
+ * @param start The inclusive starting index.
+ * @param end The exclusive ending index.
+ * @param block A lambda function that takes two Int parameters representing the start and end
+ *   indices of a paragraph.
+ */
+internal inline fun CharSequence.forEachParagraph(
+    start: Int,
+    end: Int,
+    crossinline block: (Int, Int) -> Unit
+) {
+    var paraStart = start
+    while (paraStart < end) {
+        var paraEnd = indexOf('\n', paraStart) // TODO support other paragraph separator
+        if (paraEnd == -1 || paraEnd >= end) {
+            paraEnd = end
+        } else {
+            // Include the paragraph separator in the current paragraph.
+            paraEnd++
+        }
+
+        block(paraStart, paraEnd)
+
+        paraStart = paraEnd
+    }
+}
diff --git a/text/text-vertical/src/main/java/androidx/text/vertical/VerticalTextLayout.kt b/text/text-vertical/src/main/java/androidx/text/vertical/VerticalTextLayout.kt
new file mode 100644
index 0000000..a6602f3
--- /dev/null
+++ b/text/text-vertical/src/main/java/androidx/text/vertical/VerticalTextLayout.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical
+
+import android.graphics.Canvas
+import android.text.TextPaint
+import androidx.annotation.Px
+
+/**
+ * Represents the result of laying out text vertically.
+ *
+ * This class encapsulates the result of a vertical text layout process. It stores the layout's
+ * properties and provides methods to draw the layout on a [Canvas].
+ *
+ * @property orientation The text orientation used for building this vertical layout.
+ * @property paint The [TextPaint] used for building this vertical layout. Do not mutate this paint
+ *   instance.
+ */
+public class VerticalTextLayout
+private constructor(
+    public val text: CharSequence,
+    public val start: Int,
+    public val end: Int,
+    public val paint: TextPaint,
+    @Px public val height: Float,
+    @OrientationMode public val orientation: Int,
+    private val result: LineBreaker.Result
+) {
+    /** The width constraint of the vertical text in pixels. */
+    @get:Px
+    public val width: Float
+        get() = result.width
+
+    /**
+     * Draws this text layout onto the specified [Canvas].
+     *
+     * @param canvas The [Canvas] to draw onto.
+     * @param x The horizontal offset in pixels. The drawing origin is the top-right corner.
+     * @param y The vertical offset in pixels. The drawing origin is the top-right corner.
+     */
+    public fun draw(canvas: Canvas, @Px x: Float, @Px y: Float) {
+        result.draw(canvas, x, y, paint)
+    }
+
+    /**
+     * Builder class for creating instances of [VerticalTextLayout].
+     *
+     * @param text The text to be laid out.
+     * @param start The inclusive start offset of the target text range.
+     * @param end The exclusive end offset of the target text range.
+     * @param paint The [TextPaint] instance used for laying out the text.
+     * @param height The height constraint in pixels.
+     */
+    public class Builder(
+        private val text: CharSequence,
+        private val start: Int,
+        private val end: Int,
+        private val paint: TextPaint,
+        @Px private val height: Float
+    ) {
+        private var _orientation: Int = TextOrientation.MIXED
+
+        /**
+         * Sets the text orientation.
+         *
+         * Defaults to [TextOrientation.MIXED].
+         *
+         * @param orientation The desired text orientation.
+         * @return This [Builder] instance for chaining.
+         */
+        public fun setOrientation(@OrientationMode orientation: Int): Builder = apply {
+            _orientation = orientation
+        }
+
+        /**
+         * Builds the [VerticalTextLayout] instance.
+         *
+         * @return The constructed [VerticalTextLayout].
+         */
+        public fun build(): VerticalTextLayout {
+            val lines = LineBreaker.breakTextIntoLines(text, start, end, paint, height)
+            return VerticalTextLayout(text, start, end, paint, height, _orientation, lines)
+        }
+    }
+}
diff --git a/text/text-vertical/testapp/build.gradle b/text/text-vertical/testapp/build.gradle
new file mode 100644
index 0000000..37e61d9
--- /dev/null
+++ b/text/text-vertical/testapp/build.gradle
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import androidx.build.SoftwareType
+
+plugins {
+    id("AndroidXPlugin")
+    id("AndroidXComposePlugin")
+    id("com.android.application")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+    api(libs.kotlinStdlib)
+    implementation(project(":text:text-vertical"))
+
+    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.4")
+    api("androidx.appcompat:appcompat:1.6.1")
+    api("androidx.activity:activity-compose:1.8.2")
+    implementation("androidx.compose.material3:material3:1.2.1")
+
+    api("androidx.compose.ui:ui:1.7.1")
+    api("androidx.compose.ui:ui-graphics:1.7.1")
+    api("androidx.compose.ui:ui-util:1.7.1")
+    api("androidx.compose.foundation:foundation:1.7.1")
+}
+
+androidx {
+    name = "Vertical Text TestApp"
+    type = SoftwareType.TEST_APPLICATION
+    inceptionYear = "2025"
+    description = "Contains the demo code for the vertical writing"
+}
+
+android {
+    namespace = "androidx.text.vertical.testapp"
+    compileSdk = 36
+    defaultConfig {
+        targetSdk = 36
+        minSdk = 36
+    }
+}
diff --git a/text/text-vertical/testapp/src/main/AndroidManifest.xml b/text/text-vertical/testapp/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..dcff015
--- /dev/null
+++ b/text/text-vertical/testapp/src/main/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2025 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-sdk android:minSdkVersion="36"/>
+    <application
+        android:label="Vertical Text Demo">
+        <activity android:name=".VerticalTextSampleActivity" android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/text/text-vertical/testapp/src/main/java/androidx/text/vertical/testapp/VerticalTextSampleActivity.kt b/text/text-vertical/testapp/src/main/java/androidx/text/vertical/testapp/VerticalTextSampleActivity.kt
new file mode 100644
index 0000000..5b50d30
--- /dev/null
+++ b/text/text-vertical/testapp/src/main/java/androidx/text/vertical/testapp/VerticalTextSampleActivity.kt
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical.testapp
+
+import android.graphics.Typeface
+import android.os.Bundle
+import android.text.Spanned
+import android.text.TextPaint
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.gestures.detectTransformGestures
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.PrimaryTabRow
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Tab
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.graphics.nativeCanvas
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.unit.em
+import androidx.compose.ui.unit.sp
+import androidx.text.vertical.VerticalTextLayout
+import java.util.Locale
+import kotlin.math.max
+
+class VerticalTextSampleActivity : ComponentActivity() {
+    @OptIn(ExperimentalMaterial3Api::class)
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        setContent {
+            val demos =
+                arrayOf<Pair<String, @Composable () -> Unit>>(
+                    "Long Text" to { ZoomableVerticalText { LongText(it) } },
+                    "Complex Text" to { ZoomableVerticalText { ComplexText(it) } },
+                )
+
+            Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
+                Column(modifier = Modifier.padding(innerPadding)) {
+                    var selectedTabIndex by remember { mutableIntStateOf(0) }
+                    PrimaryTabRow(selectedTabIndex = 0, modifier = Modifier.fillMaxWidth()) {
+                        demos.forEachIndexed { index, (title, _) ->
+                            Tab(
+                                selected = selectedTabIndex == index,
+                                onClick = { selectedTabIndex = index },
+                                text = { Text(title) }
+                            )
+                        }
+                    }
+                    demos[selectedTabIndex].second()
+                }
+            }
+        }
+    }
+}
+
+@Composable
+fun ZoomableVerticalText(content: @Composable (TextPaint) -> Unit) {
+    val fontSize = with(LocalDensity.current) { 32.sp.toPx() }
+    var zoom by remember { mutableFloatStateOf(1f) }
+    var offsetX by remember { mutableFloatStateOf(0f) }
+    val paint =
+        remember(zoom) {
+            TextPaint().apply {
+                textSize = fontSize * zoom
+                typeface = Typeface.SERIF
+                textLocale =
+                    Locale.Builder()
+                        .setLocale(Locale.JAPANESE)
+                        .setUnicodeLocaleKeyword("lb", "strict")
+                        .build()
+            }
+        }
+
+    Box(
+        modifier =
+            Modifier.pointerInput(Unit) {
+                    detectTapGestures(
+                        onDoubleTap = {
+                            zoom = 1f
+                            offsetX = 0f
+                        }
+                    )
+                }
+                .pointerInput(Unit) {
+                    detectTransformGestures { _, offsetChange, gestureZoom, _ ->
+                        zoom = zoom * gestureZoom
+                        offsetX = max(0f, offsetX + offsetChange.x)
+                    }
+                }
+                .graphicsLayer(translationX = offsetX)
+    ) {
+        content(paint)
+    }
+}
+
+@Composable
+fun VerticalText(
+    text: Spanned,
+    paint: TextPaint,
+    modifier: Modifier = Modifier,
+) {
+    var vTextLayout by remember { mutableStateOf<VerticalTextLayout?>(null) }
+    Layout(
+        modifier =
+            modifier.fillMaxSize().drawWithContent {
+                drawIntoCanvas { c ->
+                    vTextLayout?.draw(c.nativeCanvas, c.nativeCanvas.width.toFloat(), 0f)
+                }
+            },
+        content = {},
+    ) { _, constraints ->
+        vTextLayout =
+            VerticalTextLayout.Builder(
+                    text = text,
+                    start = 0,
+                    end = text.length,
+                    paint = paint,
+                    height = constraints.maxHeight.toFloat()
+                )
+                .build()
+        layout(constraints.maxWidth, constraints.maxHeight) {}
+    }
+}
+
+@Composable
+fun LongText(paint: TextPaint, modifier: Modifier = Modifier) {
+    VerticalText(
+        buildVerticalText {
+            text("吾輩は猫である。", mapOf("吾輩" to "わがはい", "猫" to "ねこ"))
+            text("名前はまだ無い。", mapOf("名前" to "なまえ", "無" to "な"))
+            text("\n")
+            text("どこで生まれたかとんと見当がつかぬ。", mapOf("見当" to "けんとう"))
+            text("何でも薄暗いじめじめしたところでニャーニャー泣いていた事だけは記憶している。")
+            text("吾輩はここで始めて人間というものを見た。")
+            text("しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。", mapOf("獰悪" to "どうあく"))
+            text("この書生というのは時々我々を捕えて煮て食うという話である。", mapOf("捕" to "つかま", "煮" to "に"))
+            text("しかしその当時は何という考もなかったから別段恐しいとも思わなかった。")
+            text("ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。", mapOf("掌" to "てのひら"))
+            text("掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。", mapOf("見始" to "みはじめ"))
+            text("この時妙なものだと思った感じが今でも残っている。")
+            text("第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。", mapOf("薬缶" to "やかん"))
+            text("その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。", mapOf("片端" to "かたわ", "出会" to "でく"))
+            text("のみならず顔の真中があまりに突起している。")
+            text("そうしてその穴の中から時々ぷうぷうと煙を吹く。", mapOf("煙" to "けむり"))
+            text("どうも咽せぽくて実に弱った。", mapOf("咽" to "む"))
+            text("これが人間の飲む煙草というものである事はようやくこの頃知った。", mapOf("煙草" to "たばこ"))
+            text("\n")
+        },
+        paint,
+        modifier
+    )
+}
+
+@Composable
+fun ComplexText(paint: TextPaint, modifier: Modifier = Modifier) {
+    VerticalText(
+        buildVerticalText {
+            Upright("2024")
+            text("年の")
+            ruby("クリスマス") {
+                TateChuYoko("12")
+                text("月")
+                TateChuYoko("25")
+                text("日")
+            }
+            text("に")
+            Sideways("Google Pixel")
+            text("を買う。\n")
+
+            Upright("2024")
+            text("年は")
+            TateChuYoko("2024")
+            text("年ともかけるし")
+            Sideways("2024年")
+            text("ともかけるよ。\n")
+
+            text("もちろん")
+            withStyle(textColor = Color.Red) {
+                ruby(
+                    buildVerticalText {
+                        text("インライン")
+                        withStyle(fontSize = 1.5.em) { text("スタイリング") }
+                    }
+                ) {
+                    withStyle(fontSize = 0.8.em) { Sideways("inline ") }
+                    withStyle(backgroundColor = Color.Green) { Sideways("styling") }
+                }
+                withStyle(backgroundColor = Color.LightGray) {
+                    text("も")
+                    withStyle(fontSize = 2.em) { text("可能") }
+                    text("です。\n")
+                }
+            }
+
+            TateChuYoko(
+                buildVerticalText { // Tate Chu Yoko only respect styling.
+                    text("2")
+                    withStyle(backgroundColor = Color.Red) { text("0") }
+                    withStyle(backgroundColor = Color.Green) { text("2") }
+                    text("5")
+                }
+            )
+            text("年もよろしくお願いいたします。")
+        },
+        paint,
+        modifier
+    )
+}
diff --git a/text/text-vertical/testapp/src/main/java/androidx/text/vertical/testapp/VerticalTextUtils.kt b/text/text-vertical/testapp/src/main/java/androidx/text/vertical/testapp/VerticalTextUtils.kt
new file mode 100644
index 0000000..3d86958d
--- /dev/null
+++ b/text/text-vertical/testapp/src/main/java/androidx/text/vertical/testapp/VerticalTextUtils.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.text.vertical.testapp
+
+import android.text.SpannableStringBuilder
+import android.text.Spanned
+import android.text.TextPaint
+import android.text.style.MetricAffectingSpan
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.isSpecified
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.TextUnit
+import androidx.compose.ui.unit.isSpecified
+import androidx.text.vertical.RubySpan
+import androidx.text.vertical.TextOrientationSpan
+
+const val SPAN_FLAG = Spanned.SPAN_INCLUSIVE_EXCLUSIVE
+
+class VerticalTextBuilder {
+    @Composable
+    fun Sideways(text: CharSequence) = withSpan(TextOrientationSpan.Sideways(), { this.text(text) })
+
+    @Composable
+    fun Upright(text: CharSequence) = withSpan(TextOrientationSpan.Upright(), { this.text(text) })
+
+    @Composable
+    fun TateChuYoko(text: CharSequence) =
+        withSpan(TextOrientationSpan.TextCombineUpright(), { this.text(text) })
+
+    @Composable
+    fun <R : Any> ruby(ruby: CharSequence, block: @Composable VerticalTextBuilder.() -> R): R =
+        withSpan(RubySpan.Builder(ruby).build(), block)
+
+    fun text(text: CharSequence, rubyMap: Map<String, String> = emptyMap()) {
+        val textStartOffset = result.length
+        result.append(text)
+
+        rubyMap.forEach { key, ruby ->
+            var searchOffset = textStartOffset
+            var found = result.indexOf(key, searchOffset)
+            while (found != -1) {
+                result.setSpan(RubySpan.Builder(ruby).build(), found, found + key.length, SPAN_FLAG)
+                searchOffset = found + key.length
+                found = result.indexOf(key, searchOffset)
+            }
+        }
+    }
+
+    @Composable
+    private fun <R : Any> withSpan(span: Any, block: @Composable VerticalTextBuilder.() -> R): R {
+        val index = result.length
+        val r = block(this)
+        result.setSpan(span, index, result.length, SPAN_FLAG)
+        return r
+    }
+
+    private class TextStyleSpan(
+        private val fontSize: TextUnit = TextUnit.Unspecified,
+        private val textColor: Color = Color.Unspecified,
+        private val backgroundColor: Color = Color.Unspecified,
+        private val density: Density,
+    ) : MetricAffectingSpan() {
+
+        override fun updateMeasureState(textPaint: TextPaint) {
+            if (fontSize.isSpecified) {
+                if (fontSize.isSp) {
+                    textPaint.textSize = fontSize.value * density.fontScale * density.density
+                } else {
+                    textPaint.textSize *= fontSize.value
+                }
+            }
+            if (textColor.isSpecified) {
+                textPaint.color = textColor.toArgb()
+            }
+            if (backgroundColor.isSpecified) {
+                textPaint.bgColor = backgroundColor.toArgb()
+            }
+        }
+
+        override fun updateDrawState(tp: TextPaint) = updateMeasureState(tp)
+    }
+
+    @Composable
+    fun <R : Any> withStyle(
+        fontSize: TextUnit = TextUnit.Unspecified,
+        textColor: Color = Color.Unspecified,
+        backgroundColor: Color = Color.Unspecified,
+        block: @Composable VerticalTextBuilder.() -> R
+    ): R =
+        withSpan(
+            TextStyleSpan(fontSize, textColor, backgroundColor, LocalDensity.current),
+            block,
+        )
+
+    var result = SpannableStringBuilder()
+}
+
+@Composable
+fun buildVerticalText(builder: @Composable VerticalTextBuilder.() -> Unit): SpannableStringBuilder =
+    VerticalTextBuilder().apply { this.builder() }.result
