toSvg

Function

Common
fun Path.toSvg(asDocument: Boolean = false) = buildString {
    val bounds = this@toSvg.getBounds()

    if (asDocument) {
        append("""<svg xmlns="http://www.w3.org/2000/svg" """)
        appendLine("""viewBox="${bounds.left} ${bounds.top} ${bounds.width} ${bounds.height}">""")
    }

    val iterator = this@toSvg.iterator()
    val points = FloatArray(8)
    var lastType = PathSegment.Type.Done

    if (iterator.hasNext()) {
        if (asDocument) {
            if (this@toSvg.fillType == PathFillType.EvenOdd) {
                append("""  <path fill-rule="evenodd" d="""")
            } else {
                append("""  <path d="""")
            }
        }

        while (iterator.hasNext()) {
            val type = iterator.next(points)
            when (type) {
                PathSegment.Type.Move -> {
                    append("${command(PathSegment.Type.Move, lastType)}${points[0]} ${points[1]}")
                }
                PathSegment.Type.Line -> {
                    append("${command(PathSegment.Type.Line, lastType)}${points[2]} ${points[3]}")
                }
                PathSegment.Type.Quadratic -> {
                    append(command(PathSegment.Type.Quadratic, lastType))
                    append("${points[2]} ${points[3]} ${points[4]} ${points[5]}")
                }
                PathSegment.Type.Conic -> continue // We convert conics to quadratics
                PathSegment.Type.Cubic -> {
                    append(command(PathSegment.Type.Cubic, lastType))
                    append("${points[2]} ${points[3]} ")
                    append("${points[4]} ${points[5]} ")
                    append("${points[6]} ${points[7]}")
                }
                PathSegment.Type.Close -> {
                    append(command(PathSegment.Type.Close, lastType))
                }
                PathSegment.Type.Done -> continue // Won't happen inside this loop
            }
            lastType = type
        }

        if (asDocument) {
            appendLine(""""/>""")
        }
    }
    if (asDocument) {
        appendLine("""</svg>""")
    }
}

Returns an SVG representation of this path. The caller can choose whether the returned SVG represents a fully-formed SVG document or only the path data(https://www.w3.org/TR/SVG2/paths.html#PathData). By default, only the path data is returned which can be used either with Path.addSvg or androidx.compose.ui.graphics.vector.PathParser.

Parameters

asDocumentWhen set to true, this function returns a fully-formed SVG document, otherwise returns only the path data.