diff --git a/graphics/graphics-path/build.gradle b/graphics/graphics-path/build.gradle
index b67834a..c6107a7 100644
--- a/graphics/graphics-path/build.gradle
+++ b/graphics/graphics-path/build.gradle
@@ -34,6 +34,12 @@
 
     implementation("androidx.core:core:1.12.0")
 
+    testImplementation(libs.junit)
+    testImplementation(libs.testExtJunit)
+    testImplementation(libs.testCore)
+    testImplementation(libs.testRunner)
+    testImplementation("androidx.core:core-ktx:1.12.0")
+
     androidTestImplementation("androidx.annotation:annotation:1.8.1")
     androidTestImplementation("androidx.core:core-ktx:1.12.0")
     androidTestImplementation("androidx.test:core:1.5.0@aar")
@@ -89,4 +95,5 @@
     inceptionYear = "2022"
     description = "Query segment data for android.graphics.Path objects"
     legacyDisableKotlinStrictApiMode = true
+    enableRobolectric()
 }
diff --git a/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicConverter.kt b/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicConverter.kt
index b4456e6..b04fd8c 100644
--- a/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicConverter.kt
+++ b/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicConverter.kt
@@ -65,18 +65,39 @@
 
     /** Converts the conic in [points] to a series of quadratics, which will all be stored */
     fun convert(points: FloatArray, weight: Float, tolerance: Float, offset: Int = 0) {
-        quadraticCount = internalConicToQuadratics(points, offset, quadraticData, weight, tolerance)
+        quadraticCount = conicToQuadraticsCompat(points, offset, quadraticData, weight, tolerance)
         // 3 points per quadratic, 2 floats per point, with one point of overlap
         val newDataSize = quadraticCount * 2 * 2 + 2
         if (newDataSize > quadraticData.size) {
             quadraticData = FloatArray(newDataSize)
             quadraticCount =
-                internalConicToQuadratics(points, offset, quadraticData, weight, tolerance)
+                conicToQuadraticsCompat(points, offset, quadraticData, weight, tolerance)
         }
         currentQuadratic = 0
     }
 
     /**
+     * Calls the appropriate function for the conversion from conic to quadratic.
+     *
+     * As the native library is only available for Android, it uses our own implementation for host
+     * platforms, e.g. LayoutLib and Robolectric.
+     */
+    private fun conicToQuadraticsCompat(
+        conicPoints: FloatArray,
+        offset: Int,
+        quadraticPoints: FloatArray,
+        weight: Float,
+        tolerance: Float,
+    ): Int {
+        val isDalvik = "dalvik".equals(System.getProperty("java.vm.name"), ignoreCase = true)
+        return if (isDalvik) {
+            internalConicToQuadratics(conicPoints, offset, quadraticPoints, weight, tolerance)
+        } else {
+            conicToQuadratics(conicPoints, offset, quadraticPoints, weight, tolerance)
+        }
+    }
+
+    /**
      * The actual conversion from conic to quadratic data happens in native code, in the library
      * loaded elsewhere. This JNI function wraps that native functionality.
      */
diff --git a/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicsImpl.kt b/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicsImpl.kt
new file mode 100644
index 0000000..8ebac33
--- /dev/null
+++ b/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicsImpl.kt
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.graphics.path
+
+import java.util.ArrayList
+import kotlin.math.abs
+import kotlin.math.sqrt
+
+private const val MAX_CONIC_TO_QUAD_COUNT = 5
+
+internal fun conicToQuadratics(
+    conicPoints: FloatArray,
+    offset: Int,
+    quadraticPoints: FloatArray,
+    weight: Float,
+    tolerance: Float,
+): Int {
+    val conic =
+        Conic(
+            arrayOf(
+                Point(conicPoints[0 + offset], conicPoints[1 + offset]),
+                Point(conicPoints[2 + offset], conicPoints[3 + offset]),
+                Point(conicPoints[4 + offset], conicPoints[5 + offset]),
+            ),
+            weight,
+        )
+
+    val count = conic.computeQuadraticCount(tolerance)
+    val quadraticCount = 1 shl count
+    if (quadraticCount > quadraticPoints.size) {
+        // Buffer not large enough; return necessary size to resize and try again
+        return quadraticCount
+    }
+
+    val dstPoints = ArrayList<Point>()
+    val finalCount = conic.splitIntoQuadratics(dstPoints, count)
+
+    var index = 0
+    for (p in dstPoints) {
+        quadraticPoints[index++] = p.x
+        quadraticPoints[index++] = p.y
+    }
+
+    return finalCount
+}
+
+private class Point(val x: Float, val y: Float) {
+    fun isFinite() = x.isFinite() && y.isFinite()
+}
+
+private fun add(a: Point, b: Point) = Point(a.x + b.x, a.y + b.y)
+
+private fun mul(a: Point, b: Point) = Point(a.x * b.x, a.y * b.y)
+
+private fun approxEquals(a: Float, b: Float): Boolean = abs(a - b) < 0.0001f
+
+private fun approxEquals(a: Point, b: Point) = approxEquals(a.x, b.x) && approxEquals(a.y, b.y)
+
+private fun between(a: Float, b: Float, c: Float): Boolean = (a - b) * (c - b) <= 0.0f
+
+private fun subdivide(src: Conic, pts: ArrayList<Point>, level: Int) {
+    if (level == 0) {
+        pts.add(src.points[1])
+        pts.add(src.points[2])
+    } else {
+        val s = src.split()
+        val startY = src.points[0].y
+        val endY = src.points[2].y
+        if (between(startY, src.points[1].y, endY)) {
+            val midY = s.a.points[2].y
+            if (!between(startY, midY, endY)) {
+                val closerY = if (abs(midY - startY) < abs(midY - endY)) startY else endY
+                s.a.points[2] = Point(s.a.points[2].x, closerY)
+                s.b.points[0] = Point(s.b.points[0].x, closerY)
+            }
+            if (!between(startY, s.a.points[1].y, s.a.points[2].y)) {
+                s.a.points[1] = Point(s.a.points[1].x, startY)
+            }
+            if (!between(s.b.points[0].y, s.b.points[1].y, endY)) {
+                s.b.points[1] = Point(s.b.points[1].x, endY)
+            }
+        }
+        subdivide(s.a, pts, level - 1)
+        subdivide(s.b, pts, level - 1)
+    }
+}
+
+private class Conic(val points: Array<Point>, val weight: Float) {
+    fun computeQuadraticCount(tolerance: Float): Int {
+        val a = weight - 1.0f
+        val k = a / (4.0f * (2.0f + a))
+        val x = k * (points[0].x - 2.0f * points[1].x + points[2].x)
+        val y = k * (points[0].y - 2.0f * points[1].y + points[2].y)
+
+        var error = sqrt(x * x + y * y)
+        var count = 0
+        while (count < MAX_CONIC_TO_QUAD_COUNT) {
+            if (error <= tolerance) {
+                break
+            }
+            error *= 0.25f
+            count++
+        }
+        return count
+    }
+
+    class SplitResult(val a: Conic, val b: Conic)
+
+    fun split(): SplitResult {
+        val scale = Point(1.0f / (1.0f + weight), 1.0f / (1.0f + weight))
+        val newW = sqrt(0.5f + weight * 0.5f)
+
+        val p0 = points[0]
+        val p1 = points[1]
+        val p2 = points[2]
+        val ww = Point(weight, weight)
+
+        val wp1 = mul(ww, p1)
+        var m = mul(mul(add(add(p0, add(wp1, wp1)), p2), scale), Point(0.5f, 0.5f))
+        if (!m.isFinite()) {
+            val wD = weight.toDouble()
+            val w2 = wD * 2.0
+            val scaleHalf = 1.0 / (1.0 + wD) * 0.5
+            m =
+                Point(
+                    ((p0.x.toDouble() + w2 * p1.x.toDouble() + p2.x.toDouble()) * scaleHalf)
+                        .toFloat(),
+                    ((p0.y.toDouble() + w2 * p1.y.toDouble() + p2.y.toDouble()) * scaleHalf)
+                        .toFloat(),
+                )
+        }
+        return SplitResult(
+            Conic(arrayOf(p0, mul(add(p0, wp1), scale), m), newW),
+            Conic(arrayOf(m, mul(add(wp1, p2), scale), p2), newW),
+        )
+    }
+
+    fun commonFinitePointCheck(dstPoints: ArrayList<Point>, count: Int): Int {
+        val quadCount = 1 shl count
+        val pointCount = 2 * quadCount + 1
+
+        var isFinite = true
+        for (p in dstPoints) {
+            if (!p.isFinite()) {
+                isFinite = false
+                break
+            }
+        }
+
+        if (!isFinite) {
+            for (i in 1..<pointCount) {
+                dstPoints[i] = points[1]
+            }
+        }
+
+        return quadCount
+    }
+
+    fun splitIntoQuadratics(dstPoints: ArrayList<Point>, count: Int): Int {
+        dstPoints.add(points[0])
+
+        if (count > MAX_CONIC_TO_QUAD_COUNT) {
+            val s = split()
+
+            if (
+                approxEquals(s.a.points[1], s.a.points[2]) &&
+                    approxEquals(s.b.points[0], s.b.points[1])
+            ) {
+                dstPoints.add(s.a.points[1])
+                dstPoints.add(s.a.points[1])
+                dstPoints.add(s.a.points[1])
+                dstPoints.add(s.b.points[2])
+                return commonFinitePointCheck(dstPoints, 1)
+            }
+        }
+
+        subdivide(this, dstPoints, count)
+        return commonFinitePointCheck(dstPoints, count)
+    }
+}
diff --git a/graphics/graphics-path/src/test/java/androidx/graphics/path/PathIteratorJvmTest.kt b/graphics/graphics-path/src/test/java/androidx/graphics/path/PathIteratorJvmTest.kt
new file mode 100644
index 0000000..aba3a36
--- /dev/null
+++ b/graphics/graphics-path/src/test/java/androidx/graphics/path/PathIteratorJvmTest.kt
@@ -0,0 +1,527 @@
+/*
+ * 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.graphics.path
+
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.PointF
+import android.graphics.RectF
+import androidx.core.graphics.applyCanvas
+import androidx.core.graphics.createBitmap
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import kotlin.math.abs
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.GraphicsMode
+import org.robolectric.annotation.internal.DoNotInstrument
+
+@RunWith(AndroidJUnit4::class)
+@GraphicsMode(GraphicsMode.Mode.NATIVE)
+@Config(minSdk = 35)
+@DoNotInstrument
+class PathIteratorJvmTest {
+    @Test
+    fun emptyIterator() {
+        val path = Path()
+
+        val iterator = path.iterator()
+        assertFalse(iterator.hasNext())
+        val firstSegment = iterator.next()
+        assertEquals(PathSegment.Type.Done, firstSegment.type)
+
+        var count = 0
+        for (segment in path) {
+            count++
+        }
+
+        assertEquals(0, count)
+    }
+
+    @Test
+    fun emptyPeek() {
+        val path = Path()
+        val iterator = path.iterator()
+        assertEquals(PathSegment.Type.Done, iterator.peek())
+    }
+
+    @Test
+    fun nonEmptyIterator() {
+        val path =
+            Path().apply {
+                moveTo(1.0f, 1.0f)
+                lineTo(2.0f, 2.0f)
+                close()
+            }
+
+        val iterator = path.iterator()
+        assertTrue(iterator.hasNext())
+
+        val types =
+            arrayOf(
+                PathSegment.Type.Move,
+                PathSegment.Type.Line,
+                PathSegment.Type.Close,
+                PathSegment.Type.Done,
+            )
+        val points = arrayOf(PointF(1.0f, 1.0f), PointF(2.0f, 2.0f))
+
+        var count = 0
+        for (segment in path) {
+            assertEquals(types[count], segment.type)
+            when (segment.type) {
+                PathSegment.Type.Move -> {
+                    assertEquals(points[count], segment.points[0])
+                }
+                PathSegment.Type.Line -> {
+                    assertEquals(points[count - 1], segment.points[0])
+                    assertEquals(points[count], segment.points[1])
+                }
+                else -> {}
+            }
+            // TODO: remove condition and just auto-increment count when platform change is
+            // checked in which ignores DONE during iteration
+            if (segment.type != PathSegment.Type.Done) count++
+        }
+
+        assertEquals(3, count)
+    }
+
+    @Test
+    fun peek() {
+        val path =
+            Path().apply {
+                moveTo(1.0f, 1.0f)
+                lineTo(2.0f, 2.0f)
+                close()
+            }
+
+        val iterator = path.iterator()
+        assertEquals(PathSegment.Type.Move, iterator.peek())
+    }
+
+    @Test
+    fun peekBeyond() {
+        val path = Path()
+        assertEquals(PathSegment.Type.Done, path.iterator().peek())
+
+        path.apply {
+            moveTo(1.0f, 1.0f)
+            lineTo(2.0f, 2.0f)
+            close()
+        }
+
+        val iterator = path.iterator()
+        while (iterator.hasNext()) iterator.next()
+        assertEquals(PathSegment.Type.Done, iterator.peek())
+    }
+
+    @Test
+    fun iteratorStyles() {
+        val path =
+            Path().apply {
+                moveTo(1.0f, 1.0f)
+                lineTo(2.0f, 2.0f)
+                cubicTo(3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f)
+                quadTo(7.0f, 7.0f, 8.0f, 8.0f)
+                moveTo(10.0f, 10.0f)
+                // addRoundRect() will generate conic curves on certain API levels
+                addRoundRect(RectF(12.0f, 12.0f, 36.0f, 36.0f), 8.0f, 8.0f, Path.Direction.CW)
+                close()
+            }
+
+        iteratorStylesImpl(path, PathIterator.ConicEvaluation.AsConic)
+        iteratorStylesImpl(path, PathIterator.ConicEvaluation.AsQuadratics)
+    }
+
+    private fun iteratorStylesImpl(path: Path, conicEvaluation: PathIterator.ConicEvaluation) {
+        val iterator1 = path.iterator(conicEvaluation)
+        val iterator2 = path.iterator(conicEvaluation)
+        val iterator3 = path.iterator(conicEvaluation)
+
+        val points = FloatArray(8)
+        val points2 = FloatArray(16)
+
+        while (iterator1.hasNext() || iterator2.hasNext() || iterator3.hasNext()) {
+            val segment = iterator1.next()
+            val type = iterator2.next(points)
+            val type2 = iterator3.next(points2, 8)
+
+            assertEquals(type, segment.type)
+            assertEquals(type2, segment.type)
+
+            when (type) {
+                PathSegment.Type.Move -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points2, 4, segment.points[0])
+                }
+                PathSegment.Type.Line -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points, 1, segment.points[1])
+                    assertPointsEquals(points2, 4, segment.points[0])
+                    assertPointsEquals(points2, 5, segment.points[1])
+                }
+                PathSegment.Type.Quadratic -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points, 1, segment.points[1])
+                    assertPointsEquals(points, 2, segment.points[2])
+                    assertPointsEquals(points2, 4, segment.points[0])
+                    assertPointsEquals(points2, 5, segment.points[1])
+                    assertPointsEquals(points2, 6, segment.points[2])
+                }
+                PathSegment.Type.Conic -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points, 1, segment.points[1])
+                    assertPointsEquals(points, 2, segment.points[2])
+                    // Weight is stored after all of the points
+                    assertEquals(points[6], segment.weight)
+
+                    assertPointsEquals(points2, 4, segment.points[0])
+                    assertPointsEquals(points2, 5, segment.points[1])
+                    assertPointsEquals(points2, 6, segment.points[2])
+                    // Weight is stored after all of the points
+                    assertEquals(points2[14], segment.weight)
+                }
+                PathSegment.Type.Cubic -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points, 1, segment.points[1])
+                    assertPointsEquals(points, 2, segment.points[2])
+                    assertPointsEquals(points, 3, segment.points[3])
+
+                    assertPointsEquals(points2, 4, segment.points[0])
+                    assertPointsEquals(points2, 5, segment.points[1])
+                    assertPointsEquals(points2, 6, segment.points[2])
+                    assertPointsEquals(points2, 7, segment.points[3])
+                }
+                PathSegment.Type.Close -> {}
+                PathSegment.Type.Done -> {}
+            }
+        }
+    }
+
+    @Test
+    fun done() {
+        val path = Path().apply { close() }
+
+        val segment = path.iterator().next()
+
+        assertEquals(PathSegment.Type.Done, segment.type)
+        assertEquals(0, segment.points.size)
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun close() {
+        val path =
+            Path().apply {
+                lineTo(10.0f, 12.0f)
+                close()
+            }
+
+        val iterator = path.iterator()
+        // Swallow the move
+        iterator.next()
+        // Swallow the line
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Close, segment.type)
+        assertEquals(0, segment.points.size)
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun moveTo() {
+        val path = Path().apply { moveTo(10.0f, 12.0f) }
+
+        val segment = path.iterator().next()
+
+        assertEquals(PathSegment.Type.Move, segment.type)
+        assertEquals(1, segment.points.size)
+        assertPointsEquals(PointF(10.0f, 12.0f), segment.points[0])
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun lineTo() {
+        val path =
+            Path().apply {
+                moveTo(4.0f, 6.0f)
+                lineTo(10.0f, 12.0f)
+            }
+
+        val iterator = path.iterator()
+        // Swallow the move
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Line, segment.type)
+        assertEquals(2, segment.points.size)
+        assertPointsEquals(PointF(4.0f, 6.0f), segment.points[0])
+        assertPointsEquals(PointF(10.0f, 12.0f), segment.points[1])
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun quadraticTo() {
+        val path =
+            Path().apply {
+                moveTo(4.0f, 6.0f)
+                quadTo(10.0f, 12.0f, 20.0f, 24.0f)
+            }
+
+        val iterator = path.iterator()
+        // Swallow the move
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Quadratic, segment.type)
+        assertEquals(3, segment.points.size)
+        assertPointsEquals(PointF(4.0f, 6.0f), segment.points[0])
+        assertPointsEquals(PointF(10.0f, 12.0f), segment.points[1])
+        assertPointsEquals(PointF(20.0f, 24.0f), segment.points[2])
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun cubicTo() {
+        val path =
+            Path().apply {
+                moveTo(4.0f, 6.0f)
+                cubicTo(10.0f, 12.0f, 20.0f, 24.0f, 30.0f, 36.0f)
+            }
+
+        val iterator = path.iterator()
+        // Swallow the move
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Cubic, segment.type)
+        assertEquals(4, segment.points.size)
+        assertPointsEquals(PointF(4.0f, 6.0f), segment.points[0])
+        assertPointsEquals(PointF(10.0f, 12.0f), segment.points[1])
+        assertPointsEquals(PointF(20.0f, 24.0f), segment.points[2])
+        assertPointsEquals(PointF(30.0f, 36.0f), segment.points[3])
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun conicTo() {
+        val path =
+            Path().apply {
+                addRoundRect(RectF(12.0f, 12.0f, 24.0f, 24.0f), 8.0f, 8.0f, Path.Direction.CW)
+            }
+
+        val iterator = path.iterator(PathIterator.ConicEvaluation.AsConic)
+        // Swallow the move
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Conic, segment.type)
+        assertEquals(3, segment.points.size)
+
+        assertPointsEquals(PointF(12.0f, 18.0f), segment.points[0])
+        assertPointsEquals(PointF(12.0f, 12.0f), segment.points[1])
+        assertPointsEquals(PointF(18.0f, 12.0f), segment.points[2])
+        assertEquals(0.70710677f, segment.weight)
+    }
+
+    @Test
+    fun conicAsQuadratics() {
+        val path =
+            Path().apply {
+                addRoundRect(RectF(12.0f, 12.0f, 24.0f, 24.0f), 8.0f, 8.0f, Path.Direction.CW)
+            }
+
+        for (segment in path) {
+            if (segment.type == PathSegment.Type.Conic) fail("Found conic, none expected: $segment")
+        }
+    }
+
+    @Test
+    fun convertedConics() {
+        val path1 =
+            Path().apply {
+                addRoundRect(RectF(12.0f, 12.0f, 64.0f, 64.0f), 12.0f, 12.0f, Path.Direction.CW)
+            }
+
+        val path2 = Path()
+        for (segment in path1) {
+            when (segment.type) {
+                PathSegment.Type.Move -> path2.moveTo(segment.points[0].x, segment.points[0].y)
+                PathSegment.Type.Line -> path2.lineTo(segment.points[1].x, segment.points[1].y)
+                PathSegment.Type.Quadratic ->
+                    path2.quadTo(
+                        segment.points[1].x,
+                        segment.points[1].y,
+                        segment.points[2].x,
+                        segment.points[2].y,
+                    )
+                PathSegment.Type.Conic -> fail("Unexpected conic! $segment")
+                PathSegment.Type.Cubic ->
+                    path2.cubicTo(
+                        segment.points[1].x,
+                        segment.points[1].y,
+                        segment.points[2].x,
+                        segment.points[2].y,
+                        segment.points[3].x,
+                        segment.points[3].y,
+                    )
+                PathSegment.Type.Close -> path2.close()
+                PathSegment.Type.Done -> {}
+            }
+        }
+
+        // Now with smaller error tolerance
+        val path3 = Path()
+        for (segment in
+            path1.iterator(conicEvaluation = PathIterator.ConicEvaluation.AsQuadratics, 0.001f)) {
+            when (segment.type) {
+                PathSegment.Type.Move -> path3.moveTo(segment.points[0].x, segment.points[0].y)
+                PathSegment.Type.Line -> path3.lineTo(segment.points[1].x, segment.points[1].y)
+                PathSegment.Type.Quadratic ->
+                    path3.quadTo(
+                        segment.points[1].x,
+                        segment.points[1].y,
+                        segment.points[2].x,
+                        segment.points[2].y,
+                    )
+                PathSegment.Type.Conic -> fail("Unexpected conic! $segment")
+                PathSegment.Type.Cubic ->
+                    path3.cubicTo(
+                        segment.points[1].x,
+                        segment.points[1].y,
+                        segment.points[2].x,
+                        segment.points[2].y,
+                        segment.points[3].x,
+                        segment.points[3].y,
+                    )
+                PathSegment.Type.Close -> path3.close()
+                PathSegment.Type.Done -> {}
+            }
+        }
+
+        val b1 =
+            createBitmap(76, 76).applyCanvas {
+                drawARGB(255, 255, 255, 255)
+                drawPath(
+                    path1,
+                    Paint().apply {
+                        color = argb(1.0f, 0.0f, 0.0f, 1.0f)
+                        strokeWidth = 2.0f
+                        isAntiAlias = true
+                        style = Paint.Style.STROKE
+                    },
+                )
+            }
+
+        val b2 =
+            createBitmap(76, 76).applyCanvas {
+                drawARGB(255, 255, 255, 255)
+                drawPath(
+                    path2,
+                    Paint().apply {
+                        color = argb(1.0f, 0.0f, 0.0f, 1.0f)
+                        strokeWidth = 2.0f
+                        isAntiAlias = true
+                        style = Paint.Style.STROKE
+                    },
+                )
+            }
+
+        compareBitmaps(b1, b2)
+        // Note: b1-vs-b3 is not a valid comparison; default Skia rendering does not use an
+        // error tolerance that low. The test for fine-precision in path3 was just to
+        // ensure that the system could handle the extra data and operations required
+    }
+
+    @Test
+    fun sizes() {
+        val path = Path()
+        var iterator: PathIterator = path.iterator()
+
+        assertEquals(0, iterator.calculateSize())
+
+        path.addRoundRect(RectF(12.0f, 12.0f, 64.0f, 64.0f), 8.0f, 8.0f, Path.Direction.CW)
+
+        // Skia converted
+        // Preserve conics and count
+        iterator = path.iterator(PathIterator.ConicEvaluation.AsConic)
+        assertEquals(10, iterator.calculateSize())
+        assertEquals(iterator.calculateSize(false), iterator.calculateSize())
+
+        // Convert conics and count
+        iterator = path.iterator(PathIterator.ConicEvaluation.AsQuadratics)
+        // simple size, not including conic conversion
+        assertEquals(10, iterator.calculateSize(false))
+        // now get the size with converted conics
+        assertEquals(14, iterator.calculateSize())
+    }
+}
+
+fun argb(alpha: Float, red: Float, green: Float, blue: Float) =
+    ((alpha * 255.0f + 0.5f).toInt() shl 24) or
+        ((red * 255.0f + 0.5f).toInt() shl 16) or
+        ((green * 255.0f + 0.5f).toInt() shl 8) or
+        (blue * 255.0f + 0.5f).toInt()
+
+private fun assertPointsEquals(p1: PointF, p2: PointF) {
+    assertEquals(p1.x, p2.x, 1e-6f)
+    assertEquals(p1.y, p2.y, 1e-6f)
+}
+
+private fun assertPointsEquals(p1: FloatArray, offset: Int, p2: PointF) {
+    assertEquals(p1[0 + offset * 2], p2.x, 1e-6f)
+    assertEquals(p1[1 + offset * 2], p2.y, 1e-6f)
+}
+
+private fun compareBitmaps(b1: Bitmap, b2: Bitmap) {
+    val epsilon = 1
+
+    assertEquals(b1.width, b2.width)
+    assertEquals(b1.height, b2.height)
+
+    val p1 = IntArray(b1.width * b1.height)
+    b1.getPixels(p1, 0, b1.width, 0, 0, b1.width, b1.height)
+
+    val p2 = IntArray(b2.width * b2.height)
+    b2.getPixels(p2, 0, b2.width, 0, 0, b2.width, b2.height)
+
+    for (x in 0 until b1.width) {
+        for (y in 0 until b2.width) {
+            val index = y * b1.width + x
+
+            val c1 = p1[index]
+            val c2 = p2[index]
+
+            assertTrue(abs(Color.red(c1) - Color.red(c2)) <= epsilon)
+            assertTrue(abs(Color.green(c1) - Color.green(c2)) <= epsilon)
+            assertTrue(abs(Color.blue(c1) - Color.blue(c2)) <= epsilon)
+        }
+    }
+}
