From 388a944529eccbf0f76689841e4df45eaa878572 Mon Sep 17 00:00:00 2001 From: Justin Brooks Date: Fri, 4 Oct 2024 20:29:02 -0400 Subject: [PATCH] Upgrade ktlint --- build.gradle.kts | 2 +- changelog.md | 2 +- vgo-cli/build.gradle.kts | 13 +- .../kotlin/com/jzbrooks/vgo/cli/ArgReader.kt | 9 +- .../kotlin/com/jzbrooks/vgo/cli/CliMain.kt | 41 ++++ .../main/kotlin/com/jzbrooks/vgo/cli/main.kt | 39 ---- .../kotlin/com/jzbrooks/vgo/core/Color.kt | 9 +- .../kotlin/com/jzbrooks/vgo/core/Writer.kt | 4 +- .../vgo/core/graphic/command/CommandString.kt | 41 ++-- .../core/graphic/command/CubicBezierCurve.kt | 6 +- .../graphic/command/QuadraticBezierCurve.kt | 5 +- .../graphic/command/SmoothCubicBezierCurve.kt | 5 +- .../core/optimization/BakeTransformations.kt | 9 +- .../optimization/BreakoutImplicitCommands.kt | 5 +- .../vgo/core/optimization/CommandVariant.kt | 210 ++++++++++-------- .../core/optimization/ConvertCurvesToArcs.kt | 4 +- .../vgo/core/optimization/MergePaths.kt | 5 +- .../optimization/RemoveRedundantCommands.kt | 14 +- .../SimplifyBezierCurveCommands.kt | 64 +++++- .../core/optimization/SimplifyLineCommands.kt | 9 +- .../com/jzbrooks/vgo/core/util/math/Circle.kt | 5 +- .../vgo/core/util/math/LineSegment.kt | 5 +- .../jzbrooks/vgo/core/util/math/Matrix3.kt | 9 +- .../com/jzbrooks/vgo/core/util/math/Point.kt | 29 +-- .../jzbrooks/vgo/core/util/math/Vector3.kt | 6 +- .../graphic/command/FakeCommandPrinter.kt | 25 +-- .../vgo/core/graphic/command/ParserTests.kt | 3 +- .../optimization/BakeTransformationsTests.kt | 18 +- .../optimization/SimplifyLineCommandsTests.kt | 14 +- .../vgo/core/util/math/CurvesTests.kt | 62 +++--- .../vgo/core/util/math/LineSegmentTests.kt | 16 +- .../com/jzbrooks/vgo/plugin/OutputFormat.kt | 4 +- .../vgo/plugin/ShrinkVectorArtwork.kt | 19 +- .../com/jzbrooks/vgo/plugin/VgoPluginTest.kt | 3 +- vgo/build.gradle.kts | 6 +- .../kotlin/com/jzbrooks/vgo/Application.kt | 22 +- .../ScalableVectorGraphicCommandPrinter.kt | 29 ++- .../vgo/svg/ScalableVectorGraphicReader.kt | 26 ++- .../vgo/svg/SvgOptimizationRegistry.kt | 43 ++-- .../vgo/vd/VectorDrawableCommandPrinter.kt | 29 ++- .../vd/VectorDrawableOptimizationRegistry.kt | 43 ++-- .../jzbrooks/vgo/vd/VectorDrawableReader.kt | 19 +- .../jzbrooks/vgo/vd/VectorDrawableWriter.kt | 7 +- .../kotlin/com/jzbrooks/vgo/BaselineTests.kt | 13 +- .../svg/ScalableVectorGraphicReaderTests.kt | 3 +- .../svg/ScalableVectorGraphicWriterTests.kt | 15 +- .../vgo/vd/VectorDrawableWriterTests.kt | 21 +- 47 files changed, 582 insertions(+), 408 deletions(-) create mode 100644 vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/CliMain.kt delete mode 100644 vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/main.kt diff --git a/build.gradle.kts b/build.gradle.kts index 2335e9dd..ce6898a4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,7 @@ changelog.path.set("changelog.md") subprojects { apply() configure { - version.set("1.2.1") + version.set("1.3.1") } pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { diff --git a/changelog.md b/changelog.md index e0ec1374..12bdca58 100644 --- a/changelog.md +++ b/changelog.md @@ -7,7 +7,7 @@ ### Changed - `vgo-plugin` (`com.jzbrooks.vgo.plugin`) no longer requires a particular version of Android Gradle Plugin. - Note: `:vgo` is now an abstract impmeentation of the tool which does not assume either a cli or plugin context. CLI related logic has been relocated into `:vgo-core`. + Note: `:vgo` is now an abstract implementation of the tool which does not assume either a cli or plugin context. CLI related logic has been relocated into `:vgo-core`. ### Deprecated diff --git a/vgo-cli/build.gradle.kts b/vgo-cli/build.gradle.kts index c2764d1f..52324235 100644 --- a/vgo-cli/build.gradle.kts +++ b/vgo-cli/build.gradle.kts @@ -11,13 +11,21 @@ tasks { attributes["Bundle-Version"] = project.properties["VERSION_NAME"] } - val sourceClasses = sourceSets.main.get().output.classesDirs + val sourceClasses = + sourceSets.main + .get() + .output.classesDirs inputs.files(sourceClasses) destinationDirectory.set(layout.buildDirectory.dir("libs/debug")) doFirst { from(files(sourceClasses)) - from(configurations.runtimeClasspath.get().asFileTree.files.map(::zipTree)) + from( + configurations.runtimeClasspath + .get() + .asFileTree.files + .map(::zipTree), + ) exclude( "**/*.kotlin_metadata", @@ -41,7 +49,6 @@ tasks { } } - val optimize by registering(JavaExec::class) { description = "Runs r8 on the jar application." group = "build" diff --git a/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/ArgReader.kt b/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/ArgReader.kt index 182b9277..76c50ba7 100644 --- a/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/ArgReader.kt +++ b/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/ArgReader.kt @@ -10,7 +10,9 @@ import kotlin.collections.map import kotlin.text.isNotBlank import kotlin.text.split -class ArgReader(private val args: MutableList) { +class ArgReader( + private val args: MutableList, +) { private val hasArguments get() = args.isNotEmpty() @@ -73,12 +75,11 @@ class ArgReader(private val args: MutableList) { private fun isOptionArgument( name: String, argument: String, - ): Boolean { - return if (name.length == 1) { + ): Boolean = + if (name.length == 1) { "-$name" == argument } else { "--$name" == argument } - } } } diff --git a/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/CliMain.kt b/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/CliMain.kt new file mode 100644 index 00000000..44186326 --- /dev/null +++ b/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/CliMain.kt @@ -0,0 +1,41 @@ +package com.jzbrooks.vgo.cli + +import com.jzbrooks.vgo.Application +import kotlin.system.exitProcess + +fun main(args: Array) { + val argReader = ArgReader(args.toMutableList()) + + val printHelp = argReader.readFlag("help|h") + val printVersion = argReader.readFlag("version|v") + val printStats = argReader.readFlag("stats|s") + val indent = argReader.readOption("indent")?.toIntOrNull() + + val outputs = + run { + val outputPaths = mutableListOf() + var output = argReader.readOption("output|o") + while (output != null) { + outputPaths.add(output) + output = argReader.readOption("output|o") + } + outputPaths.toList() + } + + var format = argReader.readOption("format") + + var inputs = argReader.readArguments() + + val options = + Application.Options( + printHelp = printHelp, + printVersion = printVersion, + printStats = printStats, + indent = indent, + output = outputs, + format = format, + input = inputs, + ) + + exitProcess(Application(options).run()) +} diff --git a/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/main.kt b/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/main.kt deleted file mode 100644 index 92020724..00000000 --- a/vgo-cli/src/main/kotlin/com/jzbrooks/vgo/cli/main.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.jzbrooks.vgo.cli - -import com.jzbrooks.vgo.Application -import kotlin.system.exitProcess - -fun main(args: Array) { - val argReader = ArgReader(args.toMutableList()) - - val printHelp = argReader.readFlag("help|h") - val printVersion = argReader.readFlag("version|v") - val printStats = argReader.readFlag("stats|s") - val indent = argReader.readOption("indent")?.toIntOrNull() - - val outputs = run { - val outputPaths = mutableListOf() - var output = argReader.readOption("output|o") - while (output != null) { - outputPaths.add(output) - output = argReader.readOption("output|o") - } - outputPaths.toList() - } - - var format = argReader.readOption("format") - - var inputs = argReader.readArguments() - - val options = Application.Options( - printHelp = printHelp, - printVersion = printVersion, - printStats = printStats, - indent = indent, - output = outputs, - format = format, - input = inputs - ) - - exitProcess(Application(options).run()) -} \ No newline at end of file diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/Color.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/Color.kt index cd31af80..54fd92e7 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/Color.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/Color.kt @@ -1,7 +1,9 @@ package com.jzbrooks.vgo.core @JvmInline -value class Color(private val argb: UInt) { +value class Color( + private val argb: UInt, +) { val alpha: UByte get() = (argb shr 24).toUByte() @@ -22,8 +24,8 @@ value class Color(private val argb: UInt) { operator fun component4() = blue - fun toHexString(format: HexFormat): String { - return if (alpha != 0xFF.toUByte()) { + fun toHexString(format: HexFormat): String = + if (alpha != 0xFF.toUByte()) { val pattern = "#%02x%02x%02x%02x" when (format) { HexFormat.ARGB -> @@ -50,7 +52,6 @@ value class Color(private val argb: UInt) { hexColor } } - } enum class HexFormat { RGBA, diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/Writer.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/Writer.kt index 88b602a0..6b7aed20 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/Writer.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/Writer.kt @@ -12,6 +12,8 @@ interface Writer { ) sealed class Option { - class Indent(val columns: Int) : Option() + class Indent( + val columns: Int, + ) : Option() } } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/CommandString.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/CommandString.kt index 716ee61a..9bec7fd6 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/CommandString.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/CommandString.kt @@ -3,9 +3,12 @@ package com.jzbrooks.vgo.core.graphic.command import com.jzbrooks.vgo.core.util.math.Point @JvmInline -value class CommandString(val data: String) { - fun toCommandList(): List { - return data.split(commandRegex) +value class CommandString( + val data: String, +) { + fun toCommandList(): List = + data + .split(commandRegex) .asSequence() .filter { it.isNotBlank() } .map { command -> @@ -13,7 +16,8 @@ value class CommandString(val data: String) { when { command.startsWith('M', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map(MatchResult::value) .map(String::toFloat) .chunked(2) @@ -24,7 +28,8 @@ value class CommandString(val data: String) { } command.startsWith('L', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map(MatchResult::value) .map(String::toFloat) .chunked(2) @@ -35,7 +40,8 @@ value class CommandString(val data: String) { } command.startsWith('V', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map { it.value.toFloat() } .toList() @@ -43,7 +49,8 @@ value class CommandString(val data: String) { } command.startsWith('H', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map { it.value.toFloat() } .toList() @@ -51,7 +58,8 @@ value class CommandString(val data: String) { } command.startsWith('Q', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map(MatchResult::value) .map(String::toFloat) .chunked(4) @@ -62,7 +70,8 @@ value class CommandString(val data: String) { } command.startsWith('T', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map(MatchResult::value) .map(String::toFloat) .chunked(2) @@ -73,7 +82,8 @@ value class CommandString(val data: String) { } command.startsWith('C', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map(MatchResult::value) .map(String::toFloat) .chunked(6) @@ -84,7 +94,8 @@ value class CommandString(val data: String) { } command.startsWith('S', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map(MatchResult::value) .map(String::toFloat) .chunked(4) @@ -95,7 +106,8 @@ value class CommandString(val data: String) { } command.startsWith('A', true) -> { val parameters = - number.findAll(command) + number + .findAll(command) .map(MatchResult::value) .map(String::toFloat) .chunked(7) @@ -108,11 +120,8 @@ value class CommandString(val data: String) { else -> throw IllegalStateException("Expected one of $commandRegex but was $command") } }.toList() - } - private fun mapPoint(components: List): Point { - return Point(components[0], components[1]) - } + private fun mapPoint(components: List): Point = Point(components[0], components[1]) private fun mapQuadraticBezierCurveParameter(components: List): QuadraticBezierCurve.Parameter { val control = Point(components[0], components[1]) diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/CubicBezierCurve.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/CubicBezierCurve.kt index e2c9a0cc..d42a84ae 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/CubicBezierCurve.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/CubicBezierCurve.kt @@ -6,5 +6,9 @@ data class CubicBezierCurve( override var variant: CommandVariant, override var parameters: List, ) : CubicCurve { - data class Parameter(var startControl: Point, var endControl: Point, override var end: Point) : CommandParameter + data class Parameter( + var startControl: Point, + var endControl: Point, + override var end: Point, + ) : CommandParameter } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/QuadraticBezierCurve.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/QuadraticBezierCurve.kt index d018babe..826ff983 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/QuadraticBezierCurve.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/QuadraticBezierCurve.kt @@ -6,5 +6,8 @@ data class QuadraticBezierCurve( override var variant: CommandVariant, override var parameters: List, ) : ParameterizedCommand { - data class Parameter(var control: Point, override var end: Point) : CommandParameter + data class Parameter( + var control: Point, + override var end: Point, + ) : CommandParameter } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/SmoothCubicBezierCurve.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/SmoothCubicBezierCurve.kt index de4f1e17..97d6c2ea 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/SmoothCubicBezierCurve.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/graphic/command/SmoothCubicBezierCurve.kt @@ -6,5 +6,8 @@ data class SmoothCubicBezierCurve( override var variant: CommandVariant, override var parameters: List, ) : CubicCurve { - data class Parameter(var endControl: Point, override var end: Point) : CommandParameter + data class Parameter( + var endControl: Point, + override var end: Point, + ) : CommandParameter } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/BakeTransformations.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/BakeTransformations.kt index 1fd448fc..2677567b 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/BakeTransformations.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/BakeTransformations.kt @@ -25,7 +25,9 @@ import java.util.Stack /** * Apply transformations to paths command coordinates in a group */ -class BakeTransformations : ElementVisitor, BottomUpOptimization { +class BakeTransformations : + ElementVisitor, + BottomUpOptimization { override fun visit(graphic: Graphic) {} override fun visit(clipPath: ClipPath) {} @@ -58,12 +60,11 @@ class BakeTransformations : ElementVisitor, BottomUpOptimization { group.transform = Matrix3.IDENTITY } - private fun areElementsRelocatable(group: Group): Boolean { - return group.id == null && + private fun areElementsRelocatable(group: Group): Boolean = + group.id == null && group.transform.contentsEqual(Matrix3.IDENTITY) && group.foreign.isEmpty() && group.elements.all { it is Path } - } private fun applyTransform( path: Path, diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/BreakoutImplicitCommands.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/BreakoutImplicitCommands.kt index acdb5dfa..1dbbce18 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/BreakoutImplicitCommands.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/BreakoutImplicitCommands.kt @@ -46,8 +46,8 @@ class BreakoutImplicitCommands : TopDownOptimization { path.commands = commands } - private fun divideParameters(first: ParameterizedCommand<*>): List { - return when (first) { + private fun divideParameters(first: ParameterizedCommand<*>): List = + when (first) { is MoveTo -> first.parameters.mapIndexed { i, it -> if (i == 0) first.copy(parameters = listOf(it)) else LineTo(first.variant, listOf(it)) @@ -61,5 +61,4 @@ class BreakoutImplicitCommands : TopDownOptimization { is SmoothCubicBezierCurve -> first.parameters.map { first.copy(parameters = listOf(it)) } is EllipticalArcCurve -> first.parameters.map { first.copy(parameters = listOf(it)) } } - } } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/CommandVariant.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/CommandVariant.kt index 8de8a5f6..cb911a3d 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/CommandVariant.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/CommandVariant.kt @@ -26,7 +26,9 @@ import com.jzbrooks.vgo.core.util.math.Point * or the shortest representation of coordinates * @param mode determines the operating mode of the command */ -class CommandVariant(private val mode: Mode) : TopDownOptimization { +class CommandVariant( + private val mode: Mode, +) : TopDownOptimization { private val pathStart = ArrayDeque() // Updated once per process call when computing @@ -95,17 +97,19 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { commandPoint -> - (commandPoint + currentPoint) - }.also { currentPoint = it.last().copy() }, + command.parameters + .map { commandPoint -> + (commandPoint + currentPoint) + }.also { currentPoint = it.last().copy() }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { commandPoint -> - (commandPoint - currentPoint) - }.also { currentPoint += it.last() }, + command.parameters + .map { commandPoint -> + (commandPoint - currentPoint) + }.also { currentPoint += it.last() }, ) } @@ -120,17 +124,19 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { commandPoint -> - (commandPoint + currentPoint) - }.also { currentPoint = it.last().copy() }, + command.parameters + .map { commandPoint -> + (commandPoint + currentPoint) + }.also { currentPoint = it.last().copy() }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { commandPoint -> - (commandPoint - currentPoint) - }.also { currentPoint += it.last() }, + command.parameters + .map { commandPoint -> + (commandPoint - currentPoint) + }.also { currentPoint += it.last() }, ) } @@ -143,17 +149,19 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { x -> - (x + currentPoint.x) - }.also { currentPoint = currentPoint.copy(x = it.last()) }, + command.parameters + .map { x -> + (x + currentPoint.x) + }.also { currentPoint = currentPoint.copy(x = it.last()) }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { x -> - (x - currentPoint.x) - }.also { currentPoint = currentPoint.copy(x = currentPoint.x + it.last()) }, + command.parameters + .map { x -> + (x - currentPoint.x) + }.also { currentPoint = currentPoint.copy(x = currentPoint.x + it.last()) }, ) } @@ -166,17 +174,19 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { y -> - (y + currentPoint.y) - }.also { currentPoint = currentPoint.copy(y = it.last()) }, + command.parameters + .map { y -> + (y + currentPoint.y) + }.also { currentPoint = currentPoint.copy(y = it.last()) }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { y -> - (y - currentPoint.y) - }.also { currentPoint = currentPoint.copy(y = currentPoint.y + it.last()) }, + command.parameters + .map { y -> + (y - currentPoint.y) + }.also { currentPoint = currentPoint.copy(y = currentPoint.y + it.last()) }, ) } @@ -189,29 +199,31 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { - it.copy( - startControl = it.startControl + currentPoint, - endControl = it.endControl + currentPoint, - end = it.end + currentPoint, - ) - }.also { - currentPoint = it.last().end.copy() - }, + command.parameters + .map { + it.copy( + startControl = it.startControl + currentPoint, + endControl = it.endControl + currentPoint, + end = it.end + currentPoint, + ) + }.also { + currentPoint = it.last().end.copy() + }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { - it.copy( - startControl = it.startControl - currentPoint, - endControl = it.endControl - currentPoint, - end = it.end - currentPoint, - ) - }.also { - currentPoint += it.last().end - }, + command.parameters + .map { + it.copy( + startControl = it.startControl - currentPoint, + endControl = it.endControl - currentPoint, + end = it.end - currentPoint, + ) + }.also { + currentPoint += it.last().end + }, ) } @@ -224,27 +236,29 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { - it.copy( - endControl = it.endControl + currentPoint, - end = it.end + currentPoint, - ) - }.also { - currentPoint = it.last().end.copy() - }, + command.parameters + .map { + it.copy( + endControl = it.endControl + currentPoint, + end = it.end + currentPoint, + ) + }.also { + currentPoint = it.last().end.copy() + }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { - it.copy( - endControl = it.endControl - currentPoint, - end = it.end - currentPoint, - ) - }.also { - currentPoint += it.last().end - }, + command.parameters + .map { + it.copy( + endControl = it.endControl - currentPoint, + end = it.end - currentPoint, + ) + }.also { + currentPoint += it.last().end + }, ) } @@ -257,27 +271,29 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { - it.copy( - control = it.control + currentPoint, - end = it.end + currentPoint, - ) - }.also { - currentPoint = it.last().end.copy() - }, + command.parameters + .map { + it.copy( + control = it.control + currentPoint, + end = it.end + currentPoint, + ) + }.also { + currentPoint = it.last().end.copy() + }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { - it.copy( - control = it.control - currentPoint, - end = it.end - currentPoint, - ) - }.also { - currentPoint += it.last().end - }, + command.parameters + .map { + it.copy( + control = it.control - currentPoint, + end = it.end - currentPoint, + ) + }.also { + currentPoint += it.last().end + }, ) } @@ -290,19 +306,21 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { commandPoint -> - commandPoint + currentPoint - }.also { currentPoint = it.last().copy() }, + command.parameters + .map { commandPoint -> + commandPoint + currentPoint + }.also { currentPoint = it.last().copy() }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { commandPoint -> - commandPoint - currentPoint - }.also { - currentPoint += it.last() - }, + command.parameters + .map { commandPoint -> + commandPoint - currentPoint + }.also { + currentPoint += it.last() + }, ) } @@ -315,21 +333,23 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { command.copy( variant = CommandVariant.ABSOLUTE, parameters = - command.parameters.map { - it.copy(end = it.end + currentPoint) - }.also { - currentPoint = it.last().end.copy() - }, + command.parameters + .map { + it.copy(end = it.end + currentPoint) + }.also { + currentPoint = it.last().end.copy() + }, ) } else { command.copy( variant = CommandVariant.RELATIVE, parameters = - command.parameters.map { - it.copy(end = it.end - currentPoint) - }.also { - currentPoint += it.last().end - }, + command.parameters + .map { + it.copy(end = it.end - currentPoint) + }.also { + currentPoint += it.last().end + }, ) } @@ -376,6 +396,8 @@ class CommandVariant(private val mode: Mode) : TopDownOptimization { data object Relative : Mode() - data class Compact(val printer: CommandPrinter) : Mode() + data class Compact( + val printer: CommandPrinter, + ) : Mode() } } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/ConvertCurvesToArcs.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/ConvertCurvesToArcs.kt index 351a8da1..de03a65b 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/ConvertCurvesToArcs.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/ConvertCurvesToArcs.kt @@ -22,7 +22,9 @@ import com.jzbrooks.vgo.core.util.math.toCubicBezierCurve /** * Converts cubic Bézier curves to arcs, when they are shorter. */ -class ConvertCurvesToArcs(private val printer: CommandPrinter) : TopDownOptimization { +class ConvertCurvesToArcs( + private val printer: CommandPrinter, +) : TopDownOptimization { override fun visit(graphic: Graphic) {} override fun visit(clipPath: ClipPath) {} diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/MergePaths.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/MergePaths.kt index 999dab10..beb64097 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/MergePaths.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/MergePaths.kt @@ -77,8 +77,8 @@ class MergePaths : BottomUpOptimization { private fun haveSameAttributes( first: Path, second: Path, - ): Boolean { - return first.id == second.id && + ): Boolean = + first.id == second.id && first.foreign == second.foreign && first.fill == second.fill && first.fillRule == second.fillRule && @@ -87,5 +87,4 @@ class MergePaths : BottomUpOptimization { first.strokeLineCap == second.strokeLineCap && first.strokeLineJoin == second.strokeLineJoin && first.strokeMiterLimit == second.strokeMiterLimit - } } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/RemoveRedundantCommands.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/RemoveRedundantCommands.kt index 439b259e..2e21b1c1 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/RemoveRedundantCommands.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/RemoveRedundantCommands.kt @@ -50,9 +50,10 @@ class RemoveRedundantCommands : TopDownOptimization { is VerticalLineTo -> if (current.parameters.all { it.absoluteValue < 1e-3f }) continue is HorizontalLineTo -> if (current.parameters.all { it.absoluteValue < 1e-3f }) continue is CubicBezierCurve -> - if (current.parameters.map( - CubicBezierCurve.Parameter::end, - ).all { it.isApproximately(Point.ZERO) } + if (current.parameters + .map( + CubicBezierCurve.Parameter::end, + ).all { it.isApproximately(Point.ZERO) } ) { continue } @@ -64,9 +65,10 @@ class RemoveRedundantCommands : TopDownOptimization { continue } is QuadraticBezierCurve -> - if (current.parameters.map( - QuadraticBezierCurve.Parameter::end, - ).all { it.isApproximately(Point.ZERO) } + if (current.parameters + .map( + QuadraticBezierCurve.Parameter::end, + ).all { it.isApproximately(Point.ZERO) } ) { continue } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyBezierCurveCommands.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyBezierCurveCommands.kt index 54bbce2a..23c9ccb4 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyBezierCurveCommands.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyBezierCurveCommands.kt @@ -21,7 +21,9 @@ import kotlin.math.sqrt /** * Convert curves into shorter commands where possible */ -class SimplifyBezierCurveCommands(private val tolerance: Float) : TopDownOptimization { +class SimplifyBezierCurveCommands( + private val tolerance: Float, +) : TopDownOptimization { private var skipAnother = false override fun visit(graphic: Graphic) {} @@ -99,7 +101,8 @@ class SimplifyBezierCurveCommands(private val tolerance: Float) : TopDownOptimiz ) continue@loop } - if (lastAdded !is SmoothCubicBezierCurve && lastAdded !is CubicBezierCurve && + if (lastAdded !is SmoothCubicBezierCurve && + lastAdded !is CubicBezierCurve && currentFinalParameter.startControl == Point.ZERO ) { commands.add( @@ -213,12 +216,35 @@ class SimplifyBezierCurveCommands(private val tolerance: Float) : TopDownOptimiz return false } - if (sqrt((a * parameters.last().endControl.x.toDouble() + b * parameters.last().endControl.y.toDouble()).pow(2) * d) > tolerance) { + if (sqrt( + ( + a * + parameters + .last() + .endControl.x + .toDouble() + b * + parameters + .last() + .endControl.y + .toDouble() + ).pow(2) * d, + ) > tolerance + ) { return false } if (sqrt( - (a * parameters.last().startControl.x.toDouble() + b * parameters.last().startControl.y.toDouble()).pow(2) * d, + ( + a * + parameters + .last() + .startControl.x + .toDouble() + b * + parameters + .last() + .startControl.y + .toDouble() + ).pow(2) * d, ) > tolerance ) { return false @@ -237,7 +263,20 @@ class SimplifyBezierCurveCommands(private val tolerance: Float) : TopDownOptimiz return false } - if (sqrt((a * parameters.last().endControl.x.toDouble() + b * parameters.last().endControl.y.toDouble()).pow(2) * d) > tolerance) { + if (sqrt( + ( + a * + parameters + .last() + .endControl.x + .toDouble() + b * + parameters + .last() + .endControl.y + .toDouble() + ).pow(2) * d, + ) > tolerance + ) { return false } @@ -254,7 +293,20 @@ class SimplifyBezierCurveCommands(private val tolerance: Float) : TopDownOptimiz return false } - if (sqrt((a * parameters.last().control.x.toDouble() + b * parameters.last().control.y.toDouble()).pow(2) * d) > tolerance) { + if (sqrt( + ( + a * + parameters + .last() + .control.x + .toDouble() + b * + parameters + .last() + .control.y + .toDouble() + ).pow(2) * d, + ) > tolerance + ) { return false } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyLineCommands.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyLineCommands.kt index 968f151a..d101c9a1 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyLineCommands.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyLineCommands.kt @@ -17,7 +17,9 @@ import kotlin.math.sign /** * Convert lines into shorter commands where possible */ -class SimplifyLineCommands(private val tolerance: Float) : TopDownOptimization { +class SimplifyLineCommands( + private val tolerance: Float, +) : TopDownOptimization { lateinit var commands: MutableList override fun visit(graphic: Graphic) {} @@ -48,8 +50,8 @@ class SimplifyLineCommands(private val tolerance: Float) : TopDownOptimization { path.commands = commands } - private fun process(command: Command): Command? { - return when (command) { + private fun process(command: Command): Command? = + when (command) { is LineTo -> { val firstParameter = command.parameters.first() when { @@ -81,5 +83,4 @@ class SimplifyLineCommands(private val tolerance: Float) : TopDownOptimization { } else -> command } - } } diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Circle.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Circle.kt index 1ef09f24..be64f7b1 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Circle.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Circle.kt @@ -1,3 +1,6 @@ package com.jzbrooks.vgo.core.util.math -data class Circle(var center: Point, val radius: Float) +data class Circle( + var center: Point, + val radius: Float, +) diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/LineSegment.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/LineSegment.kt index 5e86717e..f1d81b63 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/LineSegment.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/LineSegment.kt @@ -2,7 +2,10 @@ package com.jzbrooks.vgo.core.util.math import kotlin.math.abs -data class LineSegment(val first: Point, val second: Point) { +data class LineSegment( + val first: Point, + val second: Point, +) { fun intersection( other: LineSegment, tolerance: Float = 1e-3f, diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Matrix3.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Matrix3.kt index eaa658ac..042639d4 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Matrix3.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Matrix3.kt @@ -76,7 +76,9 @@ interface MutableMatrix3 : Matrix3 { } @JvmInline -private value class ArrayMatrix3(private val data: FloatArray) : MutableMatrix3 { +private value class ArrayMatrix3( + private val data: FloatArray, +) : MutableMatrix3 { override operator fun get( row: Int, column: Int, @@ -106,13 +108,12 @@ private value class ArrayMatrix3(private val data: FloatArray) : MutableMatrix3 return ArrayMatrix3(data) } - override operator fun times(other: Vector3): Vector3 { - return Vector3( + override operator fun times(other: Vector3): Vector3 = + Vector3( this[0, 0] * other.i + this[0, 1] * other.j + this[0, 2] * other.k, this[1, 0] * other.i + this[1, 1] * other.j + this[1, 2] * other.k, this[2, 0] * other.i + this[2, 1] * other.j + this[2, 2] * other.k, ) - } override fun clone(): Matrix3 = ArrayMatrix3(data.clone()) diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Point.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Point.kt index 4aab66f0..6350fb4d 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Point.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Point.kt @@ -3,33 +3,24 @@ package com.jzbrooks.vgo.core.util.math import kotlin.math.absoluteValue import kotlin.math.hypot -data class Point(val x: Float, val y: Float) { - operator fun plus(other: Point): Point { - return Point(x + other.x, y + other.y) - } +data class Point( + val x: Float, + val y: Float, +) { + operator fun plus(other: Point): Point = Point(x + other.x, y + other.y) - operator fun minus(other: Point): Point { - return Point(x - other.x, y - other.y) - } + operator fun minus(other: Point): Point = Point(x - other.x, y - other.y) - operator fun times(other: Point): Point { - return Point(x * other.x, y * other.y) - } + operator fun times(other: Point): Point = Point(x * other.x, y * other.y) - operator fun times(scalar: Float): Point { - return Point(x * scalar, y * scalar) - } + operator fun times(scalar: Float): Point = Point(x * scalar, y * scalar) - fun distanceTo(other: Point): Float { - return hypot(x - other.x, y - other.y) - } + fun distanceTo(other: Point): Float = hypot(x - other.x, y - other.y) fun isApproximately( other: Point, error: Float = 0.001f, - ): Boolean { - return (x - other.x).absoluteValue < error && (y - other.y).absoluteValue < error - } + ): Boolean = (x - other.x).absoluteValue < error && (y - other.y).absoluteValue < error companion object { val ZERO = Point(0f, 0f) diff --git a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Vector3.kt b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Vector3.kt index c5adaaff..8d6f162e 100644 --- a/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Vector3.kt +++ b/vgo-core/src/main/kotlin/com/jzbrooks/vgo/core/util/math/Vector3.kt @@ -1,6 +1,10 @@ package com.jzbrooks.vgo.core.util.math -data class Vector3(val i: Float, val j: Float, val k: Float) { +data class Vector3( + val i: Float, + val j: Float, + val k: Float, +) { constructor(point: Point) : this(point.x, point.y, 1f) fun toPoint() = Point(i, j) diff --git a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/graphic/command/FakeCommandPrinter.kt b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/graphic/command/FakeCommandPrinter.kt index b5787263..9a302be7 100644 --- a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/graphic/command/FakeCommandPrinter.kt +++ b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/graphic/command/FakeCommandPrinter.kt @@ -12,8 +12,8 @@ class FakeCommandPrinter : CommandPrinter { roundingMode = RoundingMode.HALF_UP } - override fun print(command: Command): String { - return when (command) { + override fun print(command: Command): String = + when (command) { is MoveTo -> print(command) is LineTo -> print(command) is VerticalLineTo -> print(command) @@ -26,7 +26,6 @@ class FakeCommandPrinter : CommandPrinter { is ClosePath -> "Z" else -> throw IllegalArgumentException("An unexpected command type was encountered: $command") } - } private fun print(moveTo: MoveTo): String { val command = @@ -226,8 +225,8 @@ class FakeCommandPrinter : CommandPrinter { append(print(point.y)) } - private fun print(parameter: CubicBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: CubicBezierCurve.Parameter): String = + parameter.run { buildString { append(print(startControl)) if (endControl.x >= 0) append(' ') @@ -236,30 +235,27 @@ class FakeCommandPrinter : CommandPrinter { append(print(end)) } } - } - private fun print(parameter: SmoothCubicBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: SmoothCubicBezierCurve.Parameter): String = + parameter.run { buildString { append(print(endControl)) if (end.x >= 0) append(' ') append(print(end)) } } - } - private fun print(parameter: QuadraticBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: QuadraticBezierCurve.Parameter): String = + parameter.run { buildString { append(print(control)) if (end.x >= 0) append(' ') append(print(end)) } } - } - private fun print(parameter: EllipticalArcCurve.Parameter): String { - return parameter.run { + private fun print(parameter: EllipticalArcCurve.Parameter): String = + parameter.run { buildString { append(print(radiusX)) if (radiusY >= 0) append(',') @@ -274,5 +270,4 @@ class FakeCommandPrinter : CommandPrinter { append(print(end)) } } - } } diff --git a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/graphic/command/ParserTests.kt b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/graphic/command/ParserTests.kt index 45091883..7b664920 100644 --- a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/graphic/command/ParserTests.kt +++ b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/graphic/command/ParserTests.kt @@ -206,7 +206,8 @@ class ParserTests { val commands = CommandString(pathCommandString).toCommandList() - assertThat(commands).index(0) + assertThat(commands) + .index(0) .prop("variant") { (it as ParameterizedCommand<*>).variant } .isEqualTo(CommandVariant.RELATIVE) } diff --git a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/optimization/BakeTransformationsTests.kt b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/optimization/BakeTransformationsTests.kt index ee688bae..d46e5d8e 100644 --- a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/optimization/BakeTransformationsTests.kt +++ b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/optimization/BakeTransformationsTests.kt @@ -152,7 +152,8 @@ class BakeTransformationsTests { bake.visit(group) - assertThat(group::elements).index(0) + assertThat(group::elements) + .index(0) .isInstanceOf(Path::class) .prop(Path::commands) .containsExactly( @@ -187,7 +188,8 @@ class BakeTransformationsTests { bake.visit(group) - assertThat(group::elements).index(0) + assertThat(group::elements) + .index(0) .isInstanceOf(Path::class) .prop(Path::commands) .containsExactly( @@ -220,9 +222,11 @@ class BakeTransformationsTests { bake.visit(group) - assertThat(group::elements).index(0) + assertThat(group::elements) + .index(0) .isInstanceOf(Path::class) - .prop(Path::commands).all { + .prop(Path::commands) + .all { index(0).isInstanceOf(MoveTo::class).prop(MoveTo::parameters).index(0).all { prop(Point::x).isCloseTo(-10f, 0.001f) prop(Point::y).isCloseTo(10f, 0.001f) @@ -265,9 +269,11 @@ class BakeTransformationsTests { bake.visit(group) - assertThat(group::elements).index(0) + assertThat(group::elements) + .index(0) .isInstanceOf(Path::class) - .prop(Path::commands).all { + .prop(Path::commands) + .all { index(0).isEqualTo(MoveTo(CommandVariant.ABSOLUTE, listOf(Point(10f, 10f)))) index(1).isInstanceOf(LineTo::class).all { diff --git a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyLineCommandsTests.kt b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyLineCommandsTests.kt index eb1fc89c..83099124 100644 --- a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyLineCommandsTests.kt +++ b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/optimization/SimplifyLineCommandsTests.kt @@ -115,7 +115,12 @@ class SimplifyLineCommandsTests { SimplifyLineCommands(0f).visit(path) assertThat(path.commands.filterIsInstance()).hasSize(1) - assertThat(path.commands.filterIsInstance().single().parameters).containsOnly(27f) + assertThat( + path.commands + .filterIsInstance() + .single() + .parameters, + ).containsOnly(27f) } @Test @@ -152,7 +157,12 @@ class SimplifyLineCommandsTests { SimplifyLineCommands(0f).visit(path) assertThat(path.commands.filterIsInstance()).hasSize(1) - assertThat(path.commands.filterIsInstance().single().parameters).containsOnly(20f) + assertThat( + path.commands + .filterIsInstance() + .single() + .parameters, + ).containsOnly(20f) } @Test diff --git a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/util/math/CurvesTests.kt b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/util/math/CurvesTests.kt index 8175cbff..767e4389 100644 --- a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/util/math/CurvesTests.kt +++ b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/util/math/CurvesTests.kt @@ -142,18 +142,32 @@ class CurvesTests { assertThat(curve.isConvex()).isFalse() } - data class FitCircle(val curve: CubicBezierCurve, val expectedCircle: Circle) + data class FitCircle( + val curve: CubicBezierCurve, + val expectedCircle: Circle, + ) - data class ShortcutFitCircle(val curve: SmoothCubicBezierCurve, val expectedCircle: Circle?) + data class ShortcutFitCircle( + val curve: SmoothCubicBezierCurve, + val expectedCircle: Circle?, + ) - data class ParameterizedCurve(val curve: CubicBezierCurve, val t: Float, val expected: Point) + data class ParameterizedCurve( + val curve: CubicBezierCurve, + val t: Float, + val expected: Point, + ) - data class ShortcutParameterizedCurve(val curve: SmoothCubicBezierCurve, val t: Float, val expected: Point) + data class ShortcutParameterizedCurve( + val curve: SmoothCubicBezierCurve, + val t: Float, + val expected: Point, + ) companion object { @JvmStatic - fun `Curve fits to circle`(): List { - return listOf( + fun `Curve fits to circle`(): List = + listOf( FitCircle( CubicBezierCurve( CommandVariant.RELATIVE, @@ -164,11 +178,10 @@ class CurvesTests { Circle(Point(-0.0005425225f, 5.0005436f), 5.0005436f), ), ) - } @JvmStatic - fun `Shortcut curve does not fit to circle`(): List { - return listOf( + fun `Shortcut curve does not fit to circle`(): List = + listOf( SmoothCubicBezierCurve( CommandVariant.RELATIVE, listOf( @@ -176,11 +189,10 @@ class CurvesTests { ), ), ) - } @JvmStatic - fun `Point along a curve is computed correctly`(): List { - return listOf( + fun `Point along a curve is computed correctly`(): List = + listOf( ParameterizedCurve( CubicBezierCurve( CommandVariant.RELATIVE, @@ -192,11 +204,10 @@ class CurvesTests { Point(-1.8822453f, 7.0387707f), ), ) - } @JvmStatic - fun `Point along a shortcut curve is computed correctly`(): List { - return listOf( + fun `Point along a shortcut curve is computed correctly`(): List = + listOf( ShortcutParameterizedCurve( SmoothCubicBezierCurve( CommandVariant.RELATIVE, @@ -208,11 +219,10 @@ class CurvesTests { Point(-0.099726915f, 7.381562f), ), ) - } @JvmStatic - fun `Convex curves are convex`(): List { - return listOf( + fun `Convex curves are convex`(): List = + listOf( CubicBezierCurve( CommandVariant.RELATIVE, listOf( @@ -226,11 +236,10 @@ class CurvesTests { ), ), ) - } @JvmStatic - fun `Concave curves are not convex`(): List { - return listOf( + fun `Concave curves are not convex`(): List = + listOf( CubicBezierCurve( CommandVariant.RELATIVE, listOf( @@ -244,11 +253,10 @@ class CurvesTests { ), ), ) - } @JvmStatic - fun `Convex shortcut curves are convex`(): List { - return listOf( + fun `Convex shortcut curves are convex`(): List = + listOf( SmoothCubicBezierCurve( CommandVariant.RELATIVE, listOf( @@ -268,11 +276,10 @@ class CurvesTests { ), ), ) - } @JvmStatic - fun `Concave shortcut curves are not convex`(): List { - return listOf( + fun `Concave shortcut curves are not convex`(): List = + listOf( SmoothCubicBezierCurve( CommandVariant.RELATIVE, listOf( @@ -280,6 +287,5 @@ class CurvesTests { ), ), ) - } } } diff --git a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/util/math/LineSegmentTests.kt b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/util/math/LineSegmentTests.kt index 52abcbe0..3d9cd833 100644 --- a/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/util/math/LineSegmentTests.kt +++ b/vgo-core/src/test/kotlin/com/jzbrooks/vgo/core/util/math/LineSegmentTests.kt @@ -27,12 +27,16 @@ class LineSegmentTests { assertThat(actual).isNull() } - data class Intersection(val first: LineSegment, val second: LineSegment, val result: Point?) + data class Intersection( + val first: LineSegment, + val second: LineSegment, + val result: Point?, + ) companion object { @JvmStatic - fun testIntersections(): List { - return listOf( + fun testIntersections(): List = + listOf( Intersection( LineSegment(Point(0f, 10f), Point(0f, -10f)), LineSegment(Point(-1f, 0f), Point(1f, 0f)), @@ -44,13 +48,11 @@ class LineSegmentTests { Point(2.4f, 2.4f), ), ) - } @JvmStatic - fun testParallelLinesReturnsNull(): List> { - return listOf( + fun testParallelLinesReturnsNull(): List> = + listOf( LineSegment(Point(0f, 3f), Point(0f, 3f)) to LineSegment(Point(1f, 3f), Point(1f, 3f)), ) - } } } diff --git a/vgo-plugin/src/main/kotlin/com/jzbrooks/vgo/plugin/OutputFormat.kt b/vgo-plugin/src/main/kotlin/com/jzbrooks/vgo/plugin/OutputFormat.kt index 9b57a230..6acbc8cf 100644 --- a/vgo-plugin/src/main/kotlin/com/jzbrooks/vgo/plugin/OutputFormat.kt +++ b/vgo-plugin/src/main/kotlin/com/jzbrooks/vgo/plugin/OutputFormat.kt @@ -1,6 +1,8 @@ package com.jzbrooks.vgo.plugin -enum class OutputFormat(internal val cliName: String) { +enum class OutputFormat( + internal val cliName: String, +) { SVG("svg"), VECTOR_DRAWABLE("vd"), UNCHANGED("unchanged"), diff --git a/vgo-plugin/src/main/kotlin/com/jzbrooks/vgo/plugin/ShrinkVectorArtwork.kt b/vgo-plugin/src/main/kotlin/com/jzbrooks/vgo/plugin/ShrinkVectorArtwork.kt index 7505f103..3919d06f 100644 --- a/vgo-plugin/src/main/kotlin/com/jzbrooks/vgo/plugin/ShrinkVectorArtwork.kt +++ b/vgo-plugin/src/main/kotlin/com/jzbrooks/vgo/plugin/ShrinkVectorArtwork.kt @@ -34,15 +34,16 @@ open class ShrinkVectorArtwork : DefaultTask() { @TaskAction fun shrink() { - val options = Application.Options( - printHelp = false, - printVersion = false, - printStats = showStatistics, - indent = indent.takeIf { it > 0 }?.toInt(), - output = emptyList(), - format = outputFormat.cliName, - input = files - ) + val options = + Application.Options( + printHelp = false, + printVersion = false, + printStats = showStatistics, + indent = indent.takeIf { it > 0 }?.toInt(), + output = emptyList(), + format = outputFormat.cliName, + input = files, + ) Application(options).run() } diff --git a/vgo-plugin/src/test/kotlin/com/jzbrooks/vgo/plugin/VgoPluginTest.kt b/vgo-plugin/src/test/kotlin/com/jzbrooks/vgo/plugin/VgoPluginTest.kt index 20ee83a5..f1a4de1a 100644 --- a/vgo-plugin/src/test/kotlin/com/jzbrooks/vgo/plugin/VgoPluginTest.kt +++ b/vgo-plugin/src/test/kotlin/com/jzbrooks/vgo/plugin/VgoPluginTest.kt @@ -23,7 +23,8 @@ class VgoPluginTest { @Test fun testConfiguration() { val project: Project = - ProjectBuilder.builder() + ProjectBuilder + .builder() .withProjectDir(File("src/test")) .build() diff --git a/vgo/build.gradle.kts b/vgo/build.gradle.kts index df9433fc..42086061 100644 --- a/vgo/build.gradle.kts +++ b/vgo/build.gradle.kts @@ -9,7 +9,10 @@ plugins { id("com.vanniktech.maven.publish") } -kotlin.sourceSets.getByName("main").kotlin.srcDir("src/generated/kotlin") +kotlin.sourceSets + .getByName("main") + .kotlin + .srcDir("src/generated/kotlin") dependencies { implementation(project(":vgo-core")) @@ -20,7 +23,6 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:5.11.1") testImplementation("org.junit.jupiter:junit-jupiter-params") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") - } tasks { diff --git a/vgo/src/main/kotlin/com/jzbrooks/vgo/Application.kt b/vgo/src/main/kotlin/com/jzbrooks/vgo/Application.kt index d5a131ac..e10af8af 100644 --- a/vgo/src/main/kotlin/com/jzbrooks/vgo/Application.kt +++ b/vgo/src/main/kotlin/com/jzbrooks/vgo/Application.kt @@ -20,13 +20,14 @@ import javax.xml.parsers.DocumentBuilderFactory import kotlin.math.absoluteValue import kotlin.math.roundToInt -class Application(private val options: Options) { +class Application( + private val options: Options, +) { private var printFileNames = false private var totalBytesBefore = 0.0 private var totalBytesAfter = 0.0 fun run(): Int { - if (options.printHelp) { println(HELP_MESSAGE) return 0 @@ -127,7 +128,11 @@ class Application(private val options: Options) { val document = documentBuilderFactory.newDocumentBuilder().parse(input) document.documentElement.normalize() - val rootNodes = document.childNodes.asSequence().filter { it.nodeType == Document.ELEMENT_NODE }.toList() + val rootNodes = + document.childNodes + .asSequence() + .filter { it.nodeType == Document.ELEMENT_NODE } + .toList() var graphic = when { @@ -155,7 +160,8 @@ class Application(private val options: Options) { it.nodeType == Document.ELEMENT_NODE } - com.jzbrooks.vgo.vd.parse(documentRoot) + com.jzbrooks.vgo.vd + .parse(documentRoot) } } } else { @@ -163,7 +169,8 @@ class Application(private val options: Options) { } } rootNodes.any { it.nodeName == "vector" && input.extension == "xml" } -> { - com.jzbrooks.vgo.vd.parse(rootNodes.first()) + com.jzbrooks.vgo.vd + .parse(rootNodes.first()) } else -> if (input == output) return else null } @@ -244,8 +251,8 @@ class Application(private val options: Options) { } } - private fun formatByteDescription(bytes: Long): String { - return when { + private fun formatByteDescription(bytes: Long): String = + when { bytes >= 1024 * 1024 * 1024 -> { val gigabytes = bytes / (1024.0 * 1024.0 * 1024.0) "%.2f GiB".format(gigabytes) @@ -260,7 +267,6 @@ class Application(private val options: Options) { } else -> "$bytes B" } - } private val Map.Entry.inputExists get() = key.exists() diff --git a/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicCommandPrinter.kt b/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicCommandPrinter.kt index 0367dc00..0296252b 100644 --- a/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicCommandPrinter.kt +++ b/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicCommandPrinter.kt @@ -18,7 +18,9 @@ import java.math.RoundingMode import java.text.DecimalFormat import kotlin.math.sign -class ScalableVectorGraphicCommandPrinter(private val decimalDigits: Int) : CommandPrinter { +class ScalableVectorGraphicCommandPrinter( + private val decimalDigits: Int, +) : CommandPrinter { private val formatter = DecimalFormat().apply { maximumFractionDigits = decimalDigits @@ -28,8 +30,8 @@ class ScalableVectorGraphicCommandPrinter(private val decimalDigits: Int) : Comm minimumIntegerDigits = 0 } - override fun print(command: Command): String { - return when (command) { + override fun print(command: Command): String = + when (command) { is MoveTo -> print(command) is LineTo -> print(command) is VerticalLineTo -> print(command) @@ -42,7 +44,6 @@ class ScalableVectorGraphicCommandPrinter(private val decimalDigits: Int) : Comm is ClosePath -> "Z" else -> throw IllegalArgumentException("An unexpected command type was encountered: $command") } - } private fun print(moveTo: MoveTo): String { val builder = @@ -224,8 +225,8 @@ class ScalableVectorGraphicCommandPrinter(private val decimalDigits: Int) : Comm append(print(point.y)) } - private fun print(parameter: CubicBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: CubicBezierCurve.Parameter): String = + parameter.run { buildString { append(print(startControl)) if (endControl.x.sign >= 0) append(' ') @@ -234,30 +235,27 @@ class ScalableVectorGraphicCommandPrinter(private val decimalDigits: Int) : Comm append(print(end)) } } - } - private fun print(parameter: SmoothCubicBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: SmoothCubicBezierCurve.Parameter): String = + parameter.run { buildString { append(print(endControl)) if (end.x.sign >= 0) append(' ') append(print(end)) } } - } - private fun print(parameter: QuadraticBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: QuadraticBezierCurve.Parameter): String = + parameter.run { buildString { append(print(control)) if (end.x.sign >= 0) append(' ') append(print(end)) } } - } - private fun print(parameter: EllipticalArcCurve.Parameter): String { - return parameter.run { + private fun print(parameter: EllipticalArcCurve.Parameter): String = + parameter.run { buildString { append(print(radiusX)) if (radiusY.sign >= 0) append(',') @@ -271,5 +269,4 @@ class ScalableVectorGraphicCommandPrinter(private val decimalDigits: Int) : Comm append(print(end)) } } - } } diff --git a/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicReader.kt b/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicReader.kt index c6d6ca4b..7a875c15 100644 --- a/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicReader.kt +++ b/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicReader.kt @@ -22,7 +22,8 @@ import org.w3c.dom.Text fun parse(root: Node): ScalableVectorGraphic { val elements = - root.childNodes.asSequence() + root.childNodes + .asSequence() .mapNotNull(::parseElement) .toList() @@ -46,7 +47,8 @@ private fun parseElement(node: Node): Element? { private fun parseClipPath(node: Node): ClipPath { val childElements = - node.childNodes.asSequence() + node.childNodes + .asSequence() .mapNotNull(::parseElement) .toList() @@ -59,7 +61,8 @@ private fun parseClipPath(node: Node): ClipPath { private fun parseGroupElement(node: Node): Group { val childElements = - node.childNodes.asSequence() + node.childNodes + .asSequence() .mapNotNull(::parseElement) .toList() @@ -74,7 +77,13 @@ private fun parseGroupElement(node: Node): Group { } private fun parsePathElement(node: Node): Path { - val commands = CommandString(node.attributes.removeNamedItem("d").nodeValue.toString()).toCommandList() + val commands = + CommandString( + node.attributes + .removeNamedItem("d") + .nodeValue + .toString(), + ).toCommandList() val id = node.attributes.removeOrNull("id")?.nodeValue val fill = node.attributes.extractColor("fill", Colors.BLACK) val fillRule = node.attributes.extractFillRule("fill-rule") @@ -100,7 +109,8 @@ private fun parsePathElement(node: Node): Path { private fun parseExtraElement(node: Node): Extra { val containedElements = - node.childNodes.asSequence() + node.childNodes + .asSequence() .mapNotNull(::parseElement) .toList() @@ -116,7 +126,8 @@ private fun NamedNodeMap.extractTransformMatrix(): Matrix3 { val transform = removeOrNull("transform")?.nodeValue ?: return Matrix3.IDENTITY val entries = - transform.removePrefix("matrix(") + transform + .removePrefix("matrix(") .trimEnd(')') .split(',') .map(String::toFloat) @@ -137,7 +148,8 @@ private fun NamedNodeMap.extractColor( val hex = if (value.startsWith("rgb")) { val (r, g, b) = - value.removePrefix("rgb(") + value + .removePrefix("rgb(") .trimEnd(')') .split(',') .map { it.trim().toShort() } diff --git a/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/SvgOptimizationRegistry.kt b/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/SvgOptimizationRegistry.kt index 384c90f0..fb843591 100644 --- a/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/SvgOptimizationRegistry.kt +++ b/vgo/src/main/kotlin/com/jzbrooks/vgo/svg/SvgOptimizationRegistry.kt @@ -14,24 +14,25 @@ import com.jzbrooks.vgo.core.optimization.RemoveTransparentPaths import com.jzbrooks.vgo.core.optimization.SimplifyBezierCurveCommands import com.jzbrooks.vgo.core.optimization.SimplifyLineCommands -class SvgOptimizationRegistry : OptimizationRegistry( - bottomUpOptimizations = - listOf( - BakeTransformations(), - CollapseGroups(), - RemoveEmptyGroups(), - MergePaths(), - ), - topDownOptimizations = - listOf( - RemoveTransparentPaths(), - BreakoutImplicitCommands(), - CommandVariant(CommandVariant.Mode.Relative), - SimplifyLineCommands(1e-3f), - ConvertCurvesToArcs(ScalableVectorGraphicCommandPrinter(3)), - SimplifyBezierCurveCommands(1e-3f), - RemoveRedundantCommands(), - CommandVariant(CommandVariant.Mode.Compact(ScalableVectorGraphicCommandPrinter(3))), - Polycommands(), - ), -) +class SvgOptimizationRegistry : + OptimizationRegistry( + bottomUpOptimizations = + listOf( + BakeTransformations(), + CollapseGroups(), + RemoveEmptyGroups(), + MergePaths(), + ), + topDownOptimizations = + listOf( + RemoveTransparentPaths(), + BreakoutImplicitCommands(), + CommandVariant(CommandVariant.Mode.Relative), + SimplifyLineCommands(1e-3f), + ConvertCurvesToArcs(ScalableVectorGraphicCommandPrinter(3)), + SimplifyBezierCurveCommands(1e-3f), + RemoveRedundantCommands(), + CommandVariant(CommandVariant.Mode.Compact(ScalableVectorGraphicCommandPrinter(3))), + Polycommands(), + ), + ) diff --git a/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableCommandPrinter.kt b/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableCommandPrinter.kt index b79925ed..f0606dd2 100644 --- a/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableCommandPrinter.kt +++ b/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableCommandPrinter.kt @@ -18,7 +18,9 @@ import java.math.RoundingMode import java.text.DecimalFormat import kotlin.math.sign -class VectorDrawableCommandPrinter(private val decimalDigits: Int) : CommandPrinter { +class VectorDrawableCommandPrinter( + private val decimalDigits: Int, +) : CommandPrinter { private val formatter = DecimalFormat().apply { maximumFractionDigits = decimalDigits @@ -27,8 +29,8 @@ class VectorDrawableCommandPrinter(private val decimalDigits: Int) : CommandPrin roundingMode = RoundingMode.HALF_UP } - override fun print(command: Command): String { - return when (command) { + override fun print(command: Command): String = + when (command) { is MoveTo -> print(command) is LineTo -> print(command) is VerticalLineTo -> print(command) @@ -41,7 +43,6 @@ class VectorDrawableCommandPrinter(private val decimalDigits: Int) : CommandPrin is ClosePath -> "Z" else -> throw IllegalArgumentException("An unexpected command type was encountered: $command") } - } private fun print(moveTo: MoveTo): String { val command = @@ -241,8 +242,8 @@ class VectorDrawableCommandPrinter(private val decimalDigits: Int) : CommandPrin append(print(point.y)) } - private fun print(parameter: CubicBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: CubicBezierCurve.Parameter): String = + parameter.run { buildString { append(print(startControl)) if (endControl.x >= 0) append(' ') @@ -251,30 +252,27 @@ class VectorDrawableCommandPrinter(private val decimalDigits: Int) : CommandPrin append(print(end)) } } - } - private fun print(parameter: SmoothCubicBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: SmoothCubicBezierCurve.Parameter): String = + parameter.run { buildString { append(print(endControl)) if (end.x >= 0) append(' ') append(print(end)) } } - } - private fun print(parameter: QuadraticBezierCurve.Parameter): String { - return parameter.run { + private fun print(parameter: QuadraticBezierCurve.Parameter): String = + parameter.run { buildString { append(print(control)) if (end.x >= 0) append(' ') append(print(end)) } } - } - private fun print(parameter: EllipticalArcCurve.Parameter): String { - return parameter.run { + private fun print(parameter: EllipticalArcCurve.Parameter): String = + parameter.run { buildString { append(print(radiusX)) if (radiusY >= 0) append(',') @@ -289,5 +287,4 @@ class VectorDrawableCommandPrinter(private val decimalDigits: Int) : CommandPrin append(print(end)) } } - } } diff --git a/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableOptimizationRegistry.kt b/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableOptimizationRegistry.kt index edfb3065..f5f4640e 100644 --- a/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableOptimizationRegistry.kt +++ b/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableOptimizationRegistry.kt @@ -14,24 +14,25 @@ import com.jzbrooks.vgo.core.optimization.RemoveTransparentPaths import com.jzbrooks.vgo.core.optimization.SimplifyBezierCurveCommands import com.jzbrooks.vgo.core.optimization.SimplifyLineCommands -class VectorDrawableOptimizationRegistry : OptimizationRegistry( - bottomUpOptimizations = - listOf( - BakeTransformations(), - CollapseGroups(), - RemoveEmptyGroups(), - MergePaths(), - ), - topDownOptimizations = - listOf( - RemoveTransparentPaths(), - BreakoutImplicitCommands(), - CommandVariant(CommandVariant.Mode.Relative), - SimplifyLineCommands(1e-3f), - ConvertCurvesToArcs(VectorDrawableCommandPrinter(3)), - SimplifyBezierCurveCommands(1e-3f), - RemoveRedundantCommands(), - CommandVariant(CommandVariant.Mode.Compact(VectorDrawableCommandPrinter(3))), - Polycommands(), - ), -) +class VectorDrawableOptimizationRegistry : + OptimizationRegistry( + bottomUpOptimizations = + listOf( + BakeTransformations(), + CollapseGroups(), + RemoveEmptyGroups(), + MergePaths(), + ), + topDownOptimizations = + listOf( + RemoveTransparentPaths(), + BreakoutImplicitCommands(), + CommandVariant(CommandVariant.Mode.Relative), + SimplifyLineCommands(1e-3f), + ConvertCurvesToArcs(VectorDrawableCommandPrinter(3)), + SimplifyBezierCurveCommands(1e-3f), + RemoveRedundantCommands(), + CommandVariant(CommandVariant.Mode.Compact(VectorDrawableCommandPrinter(3))), + Polycommands(), + ), + ) diff --git a/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableReader.kt b/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableReader.kt index 197572ac..30c1b117 100644 --- a/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableReader.kt +++ b/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableReader.kt @@ -26,7 +26,8 @@ import kotlin.math.sin fun parse(root: Node): VectorDrawable { val elements = - root.childNodes.asSequence() + root.childNodes + .asSequence() .mapNotNull(::parseElement) .toList() @@ -50,7 +51,8 @@ private fun parseElement(node: Node): Element? { private fun parseGroup(node: Node): Group { val groupChildElements = - node.childNodes.asSequence() + node.childNodes + .asSequence() .mapNotNull(::parseElement) .toList() @@ -155,7 +157,8 @@ private fun parseClipPath(node: Node): ClipPath { private fun parseExtraElement(node: Node): Extra { val containedElements = - node.childNodes.asSequence() + node.childNodes + .asSequence() .mapNotNull(::parseElement) .toList() @@ -179,9 +182,13 @@ private fun NamedNodeMap.computeTransformationMatrix(): Matrix3 { val rotation = removeFloatOrNull("android:rotation") - if (scaleX == null && scaleY == null && - translationX == null && translationY == null && - pivotX == null && pivotY == null && rotation == null + if (scaleX == null && + scaleY == null && + translationX == null && + translationY == null && + pivotX == null && + pivotY == null && + rotation == null ) { return Matrix3.IDENTITY } diff --git a/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableWriter.kt b/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableWriter.kt index e27aff51..63305630 100644 --- a/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableWriter.kt +++ b/vgo/src/main/kotlin/com/jzbrooks/vgo/vd/VectorDrawableWriter.kt @@ -22,7 +22,9 @@ import kotlin.math.abs import kotlin.math.atan import kotlin.math.hypot -class VectorDrawableWriter(override val options: Set = emptySet()) : Writer { +class VectorDrawableWriter( + override val options: Set = emptySet(), +) : Writer { private val commandPrinter = VectorDrawableCommandPrinter(3) private val formatter = @@ -145,7 +147,8 @@ class VectorDrawableWriter(override val options: Set = emptySet() is ClipPath -> { document.createElement("clip-path").apply { val data = - (element.elements[0] as Path).commands + (element.elements[0] as Path) + .commands .joinToString(separator = "", transform = commandPrinter::print) setAttribute("android:pathData", data) diff --git a/vgo/src/test/kotlin/com/jzbrooks/vgo/BaselineTests.kt b/vgo/src/test/kotlin/com/jzbrooks/vgo/BaselineTests.kt index 0f56b352..9d2c1d61 100644 --- a/vgo/src/test/kotlin/com/jzbrooks/vgo/BaselineTests.kt +++ b/vgo/src/test/kotlin/com/jzbrooks/vgo/BaselineTests.kt @@ -85,7 +85,8 @@ class BaselineTests { // live in src/test/resources/baseline and are suffixed with _optimized private val assets: List> = try { - Files.list(Paths.get("src/test/resources")) + Files + .list(Paths.get("src/test/resources")) .asSequence() .filterNot { Files.isDirectory(it) } .map { unoptimizedFile -> @@ -99,17 +100,15 @@ class BaselineTests { } @JvmStatic - fun provideUnoptimizedAssets(): List { - return assets.map { + fun provideUnoptimizedAssets(): List = + assets.map { Arguments.of(it.first) } - } @JvmStatic - fun provideUnoptimizedAndOptimizedAssets(): List { - return assets.map { + fun provideUnoptimizedAndOptimizedAssets(): List = + assets.map { Arguments.of(it.first, it.second) } - } } } diff --git a/vgo/src/test/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicReaderTests.kt b/vgo/src/test/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicReaderTests.kt index 1b08759e..52696dba 100644 --- a/vgo/src/test/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicReaderTests.kt +++ b/vgo/src/test/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicReaderTests.kt @@ -111,7 +111,8 @@ class ScalableVectorGraphicReaderTests { fun testStoreIdForPath() { val graphic: Graphic = parse(node) - assertThat(graphic::elements).index(0) + assertThat(graphic::elements) + .index(0) .isInstanceOf(Path::class) .prop(Path::id) .isEqualTo("heart") diff --git a/vgo/src/test/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicWriterTests.kt b/vgo/src/test/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicWriterTests.kt index 386cd3fe..b8241036 100644 --- a/vgo/src/test/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicWriterTests.kt +++ b/vgo/src/test/kotlin/com/jzbrooks/vgo/svg/ScalableVectorGraphicWriterTests.kt @@ -107,7 +107,9 @@ class ScalableVectorGraphicWriterTests { ScalableVectorGraphicWriter().write(graphicWithGroup, memoryStream) val output = memoryStream.toDocument() - val groupChildren = output.firstChild.firstChild.childNodes.toList() + val groupChildren = + output.firstChild.firstChild.childNodes + .toList() assertThat(groupChildren).hasSameSizeAs(graphic.elements) } @@ -141,18 +143,21 @@ class ScalableVectorGraphicWriterTests { ScalableVectorGraphicWriter().write(graphic, memoryStream) val output = memoryStream.toDocument() - val extraChildren = output.firstChild.childNodes.item(1).childNodes.toList() + val extraChildren = + output.firstChild.childNodes + .item(1) + .childNodes + .toList() assertThat(extraChildren).index(0).hasName("g") } } - private fun ByteArrayOutputStream.toDocument(): Document { - return DocumentBuilderFactory + private fun ByteArrayOutputStream.toDocument(): Document = + DocumentBuilderFactory .newInstance() .newDocumentBuilder() .parse(ByteArrayInputStream(toByteArray())) - } companion object { val graphic = diff --git a/vgo/src/test/kotlin/com/jzbrooks/vgo/vd/VectorDrawableWriterTests.kt b/vgo/src/test/kotlin/com/jzbrooks/vgo/vd/VectorDrawableWriterTests.kt index ed25aae3..4f0a2442 100644 --- a/vgo/src/test/kotlin/com/jzbrooks/vgo/vd/VectorDrawableWriterTests.kt +++ b/vgo/src/test/kotlin/com/jzbrooks/vgo/vd/VectorDrawableWriterTests.kt @@ -65,7 +65,9 @@ class VectorDrawableWriterTests { val output = memoryStream.toDocument() val firstGenNodes = output.firstChild.childNodes.toList() - val transformGroupNodes = output.firstChild.firstChild.childNodes.toList() + val transformGroupNodes = + output.firstChild.firstChild.childNodes + .toList() assertThat(firstGenNodes + transformGroupNodes) .transform("path element count") { it.count { item -> item.nodeName == "path" } } @@ -129,7 +131,9 @@ class VectorDrawableWriterTests { VectorDrawableWriter().write(graphic, memoryStream) val output = memoryStream.toDocument() - val groupChildren = output.firstChild.firstChild.childNodes.toList() + val groupChildren = + output.firstChild.firstChild.childNodes + .toList() assertThat(groupChildren).hasSameSizeAs((graphic.elements[0] as Group).elements) } @@ -154,7 +158,9 @@ class VectorDrawableWriterTests { VectorDrawableWriter().write(graphic, memoryStream) val output = memoryStream.toDocument() - val extraNode = output.firstChild.firstChild.childNodes.item(1) + val extraNode = + output.firstChild.firstChild.childNodes + .item(1) assertThat(extraNode).hasName("bicycle") } @@ -166,18 +172,19 @@ class VectorDrawableWriterTests { VectorDrawableWriter().write(graphic, memoryStream) val output = memoryStream.toDocument() - val extraNode = output.firstChild.firstChild.childNodes.item(1) + val extraNode = + output.firstChild.firstChild.childNodes + .item(1) assertThat(extraNode.firstChild).hasName("group") } } - private fun ByteArrayOutputStream.toDocument(): Document { - return DocumentBuilderFactory + private fun ByteArrayOutputStream.toDocument(): Document = + DocumentBuilderFactory .newInstance() .newDocumentBuilder() .parse(ByteArrayInputStream(this.toByteArray())) - } companion object { val graphic =