All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jzbrooks.vgo.vd.VectorDrawableCommandPrinter.kt Maven / Gradle / Ivy

package com.jzbrooks.vgo.vd

import com.jzbrooks.vgo.core.graphic.command.ClosePath
import com.jzbrooks.vgo.core.graphic.command.Command
import com.jzbrooks.vgo.core.graphic.command.CommandPrinter
import com.jzbrooks.vgo.core.graphic.command.CommandVariant
import com.jzbrooks.vgo.core.graphic.command.CubicBezierCurve
import com.jzbrooks.vgo.core.graphic.command.EllipticalArcCurve
import com.jzbrooks.vgo.core.graphic.command.HorizontalLineTo
import com.jzbrooks.vgo.core.graphic.command.LineTo
import com.jzbrooks.vgo.core.graphic.command.MoveTo
import com.jzbrooks.vgo.core.graphic.command.QuadraticBezierCurve
import com.jzbrooks.vgo.core.graphic.command.SmoothCubicBezierCurve
import com.jzbrooks.vgo.core.graphic.command.SmoothQuadraticBezierCurve
import com.jzbrooks.vgo.core.graphic.command.VerticalLineTo
import com.jzbrooks.vgo.core.util.math.Point
import java.math.RoundingMode
import java.text.DecimalFormat

class VectorDrawableCommandPrinter(private val decimalDigits: Int) : CommandPrinter {
    private val formatter = DecimalFormat().apply {
        maximumFractionDigits = decimalDigits
        isDecimalSeparatorAlwaysShown = false
        roundingMode = RoundingMode.HALF_UP
    }

    override fun print(command: Command): String {
        return when (command) {
            is MoveTo -> print(command)
            is LineTo -> print(command)
            is VerticalLineTo -> print(command)
            is HorizontalLineTo -> print(command)
            is CubicBezierCurve -> print(command)
            is SmoothCubicBezierCurve -> print(command)
            is QuadraticBezierCurve -> print(command)
            is SmoothQuadraticBezierCurve -> print(command)
            is EllipticalArcCurve -> print(command)
            is ClosePath -> "Z"
            else -> throw IllegalArgumentException("An unexpected command type was encountered: $command")
        }
    }

    private fun print(moveTo: MoveTo): String {
        val command = when (moveTo.variant) {
            CommandVariant.ABSOLUTE -> 'M'
            CommandVariant.RELATIVE -> 'm'
        }

        return buildString {
            append(command)
            append(print(moveTo.parameters.first()))

            for (parameter in moveTo.parameters.drop(1)) {
                if (parameter.x >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(lineTo: LineTo): String {
        val command = when (lineTo.variant) {
            CommandVariant.ABSOLUTE -> 'L'
            CommandVariant.RELATIVE -> 'l'
        }

        return buildString {
            append(command)
            append(print(lineTo.parameters.first()))

            for (parameter in lineTo.parameters.drop(1)) {
                if (parameter.x >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(verticalLineTo: VerticalLineTo): String {
        val command = when (verticalLineTo.variant) {
            CommandVariant.ABSOLUTE -> 'V'
            CommandVariant.RELATIVE -> 'v'
        }

        return buildString {
            append(command)
            append(print(verticalLineTo.parameters.first()))

            for (parameter in verticalLineTo.parameters.drop(1)) {
                if (parameter >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(horizontalLineTo: HorizontalLineTo): String {
        val command = when (horizontalLineTo.variant) {
            CommandVariant.ABSOLUTE -> 'H'
            CommandVariant.RELATIVE -> 'h'
        }

        return buildString {
            append(command)
            append(print(horizontalLineTo.parameters.first()))

            for (parameter in horizontalLineTo.parameters.drop(1)) {
                if (parameter >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(cubicBezierCurve: CubicBezierCurve): String {
        val command = when (cubicBezierCurve.variant) {
            CommandVariant.ABSOLUTE -> 'C'
            CommandVariant.RELATIVE -> 'c'
        }

        return buildString {
            append(command)
            append(print(cubicBezierCurve.parameters.first()))

            for (parameter in cubicBezierCurve.parameters.drop(1)) {
                if (parameter.startControl.x >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(smoothCubicBezierCurve: SmoothCubicBezierCurve): String {
        val command = when (smoothCubicBezierCurve.variant) {
            CommandVariant.ABSOLUTE -> 'S'
            CommandVariant.RELATIVE -> 's'
        }

        return buildString {
            append(command)
            append(print(smoothCubicBezierCurve.parameters.first()))

            for (parameter in smoothCubicBezierCurve.parameters.drop(1)) {
                if (parameter.endControl.x >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(quadraticBezierCurve: QuadraticBezierCurve): String {
        val command = when (quadraticBezierCurve.variant) {
            CommandVariant.ABSOLUTE -> 'Q'
            CommandVariant.RELATIVE -> 'q'
        }

        return buildString {
            append(command)
            append(print(quadraticBezierCurve.parameters.first()))

            for (parameter in quadraticBezierCurve.parameters.drop(1)) {
                if (parameter.control.x >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(smoothQuadraticBezierCurve: SmoothQuadraticBezierCurve): String {
        val command = when (smoothQuadraticBezierCurve.variant) {
            CommandVariant.ABSOLUTE -> 'T'
            CommandVariant.RELATIVE -> 't'
        }

        return buildString {
            append(command)
            append(print(smoothQuadraticBezierCurve.parameters.first()))

            for (parameter in smoothQuadraticBezierCurve.parameters.drop(1)) {
                if (parameter.x >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(ellipticalArcCurve: EllipticalArcCurve): String {
        val command = when (ellipticalArcCurve.variant) {
            CommandVariant.ABSOLUTE -> 'A'
            CommandVariant.RELATIVE -> 'a'
        }

        return buildString {
            append(command)
            append(print(ellipticalArcCurve.parameters.first()))

            for (parameter in ellipticalArcCurve.parameters.drop(1)) {
                if (parameter.radiusX >= 0) {
                    append(' ')
                }

                append(print(parameter))
            }
        }
    }

    private fun print(float: Float) = formatter.format(float)

    private fun print(point: Point) = buildString {
        append(print(point.x))
        append(',')
        append(print(point.y))
    }

    private fun print(parameter: CubicBezierCurve.Parameter): String {
        return parameter.run {
            buildString {
                append(print(startControl))
                if (endControl.x >= 0) append(' ')
                append(print(endControl))
                if (end.x >= 0) append(' ')
                append(print(end))
            }
        }
    }

    private fun print(parameter: SmoothCubicBezierCurve.Parameter): String {
        return parameter.run {
            buildString {
                append(print(endControl))
                if (end.x >= 0) append(' ')
                append(print(end))
            }
        }
    }

    private fun print(parameter: QuadraticBezierCurve.Parameter): String {
        return parameter.run {
            buildString {
                append(print(control))
                if (end.x >= 0) append(' ')
                append(print(end))
            }
        }
    }

    private fun print(parameter: EllipticalArcCurve.Parameter): String {
        return parameter.run {
            buildString {
                append(print(radiusX))
                if (radiusY >= 0) append(',')
                append(print(radiusY))
                if (angle >= 0) append(',')
                append(print(angle))
                append(',')
                append(arc.ordinal)
                append(',')
                append(sweep.ordinal)
                append(',')
                append(print(end))
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy