From ac2a5c5725ec31961be1db731deb9269606abc01 Mon Sep 17 00:00:00 2001 From: brymher Date: Sun, 20 Mar 2022 01:21:38 +0300 Subject: [PATCH 1/8] Removed nullable --- .../br/com/devsrsouza/svg2compose/Svg2Compose.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt index f012a7b4..9b160b48 100644 --- a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt +++ b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt @@ -38,14 +38,15 @@ object Svg2Compose { vectorsDirectory.walkTopDown() .maxDepth(10) .onEnter { file -> - val dirIcons = file.listFiles() + val dirIcons = (file.listFiles() ?: arrayOf()) + .filterNotNull() .filter { it.isDirectory.not() } .filter { it.extension.equals(type.extension, ignoreCase = true) } val previousGroup = groupStack.peekOrNull() // if there is no previous group, this is the root dir, and the group name should be the accessorName - val groupName = if(previousGroup == null) accessorName else file.name.toKotlinPropertyName() + val groupName = if (previousGroup == null) accessorName else file.name.toKotlinPropertyName() val groupPackage = previousGroup?.let { group -> "${group.groupPackage}.${group.groupName.second.toLowerCase()}" } ?: "$applicationIconPackage" val iconsPackage = "$groupPackage.${groupName.toLowerCase()}" @@ -57,7 +58,7 @@ object Svg2Compose { val generatedIconsMemberNames: Map = - if(dirIcons.isNotEmpty()) { + if (dirIcons.isNotEmpty()) { val drawables: List> = when (type) { VectorType.SVG -> dirIcons.map { val iconName = nameRelative(it).withoutExtension @@ -107,7 +108,7 @@ object Svg2Compose { childGroups = emptyList() ) - if(previousGroup != null) { + if (previousGroup != null) { groupStack.pop() groupStack.push(previousGroup.copy(childGroups = previousGroup.childGroups + result)) } @@ -117,7 +118,7 @@ object Svg2Compose { true } .onLeave { - val group = if(groupStack.size > 1) + val group = if (groupStack.size > 1) groupStack.pop() else groupStack.peek() From 1a98691717f3f64c0454e31b31d96c89951a4491 Mon Sep 17 00:00:00 2001 From: brymher Date: Sun, 20 Mar 2022 01:25:08 +0300 Subject: [PATCH 2/8] Updated to kotlin 1.6.10: Tested --- build.gradle.kts | 6 +- src/test/kotlin/TestMain.kt | 66 +++++++++++++++++++ src/test/resources/icons/branch.svg | 15 +++++ src/test/resources/icons/ic_balance_scale.svg | 25 +++++++ 4 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 src/test/kotlin/TestMain.kt create mode 100644 src/test/resources/icons/branch.svg create mode 100644 src/test/resources/icons/ic_balance_scale.svg diff --git a/build.gradle.kts b/build.gradle.kts index 548b4f6a..042e4c2f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version "1.5.21" + kotlin("jvm") version "1.6.10" id("maven-publish") } @@ -15,10 +15,10 @@ repositories { } dependencies { - implementation("com.google.guava:guava:23.0") + implementation("com.google.guava:guava:31.1-jre") implementation("com.android.tools:sdk-common:27.2.0-alpha16") implementation("com.android.tools:common:27.2.0-alpha16") - implementation("com.squareup:kotlinpoet:1.9.0") + implementation("com.squareup:kotlinpoet:1.10.2") implementation("org.ogce:xpp3:1.1.6") testImplementation(kotlin("test-junit")) diff --git a/src/test/kotlin/TestMain.kt b/src/test/kotlin/TestMain.kt new file mode 100644 index 00000000..6836fa9e --- /dev/null +++ b/src/test/kotlin/TestMain.kt @@ -0,0 +1,66 @@ +package br.com.devsrsouza.svg2compose + +import org.junit.Test +import java.io.File +import kotlin.test.assertEquals + +class TestMain { + + @Test + fun traverseGeneratorTest() { + val iconsDir = File("src/test/resources/icons") + val destinationDir = File("src/test/resources/generated").apply { mkdirs() } + + assert(iconsDir.exists()) { + "Make sure to add icons into res dir. Default test icons have been provided" + } + + assert(destinationDir.exists()) { + "Icons destination dir wasn't created ${destinationDir.path}" + } + + Svg2Compose.parse( + applicationIconPackage = "br.com.compose.icons", + accessorName = "EvaIcons", + outputSourceDirectory = destinationDir, + vectorsDirectory = iconsDir, + iconNameTransformer = { name, group -> + name.removeSuffix(group, ignoreCase = true) + } + ) + + val generatedIconsDir = File(destinationDir, "br/com/compose/icons") + + assert(generatedIconsDir.exists()) { + "Icons weren't generated" + } + + destinationDir.deleteRecursively() + + } + + private fun String.removeSuffix(suffix: String, ignoreCase: Boolean): String { + return if (ignoreCase) { + val index = lastIndexOf(suffix, ignoreCase = true) + + if (index > -1) substring(0, index) else this + } else { + removeSuffix(suffix) + } + } + + @Test + fun testCamelCase() { + val iconName = "IconName" + + assertEquals(iconName, "icon-name".camelCase) + assertEquals(iconName, "icon name".camelCase) + assertEquals(iconName, "icon_name".camelCase) + } + + val String.camelCase: String + get() = trim().split(" ", "-", "_").joinToString("") { + it[0].uppercase() + it.substring(1, it.length) + } +} + diff --git a/src/test/resources/icons/branch.svg b/src/test/resources/icons/branch.svg new file mode 100644 index 00000000..e468352e --- /dev/null +++ b/src/test/resources/icons/branch.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/test/resources/icons/ic_balance_scale.svg b/src/test/resources/icons/ic_balance_scale.svg new file mode 100644 index 00000000..cb76ac43 --- /dev/null +++ b/src/test/resources/icons/ic_balance_scale.svg @@ -0,0 +1,25 @@ + + + + + + + From 0fdc1c79f93090e81e89920ad5bb03a515693350 Mon Sep 17 00:00:00 2001 From: brymher Date: Sun, 20 Mar 2022 01:41:25 +0300 Subject: [PATCH 3/8] Added generated icons test. Fixed Invalid prefix --- .../icons/generator/VectorAssetGenerator.kt | 3 +-- .../com/devsrsouza/svg2compose/Svg2Compose.kt | 11 ++++---- src/test/kotlin/TestMain.kt | 25 +++++++++++++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/VectorAssetGenerator.kt b/src/main/kotlin/androidx/compose/material/icons/generator/VectorAssetGenerator.kt index 98918681..579f2505 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/VectorAssetGenerator.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/VectorAssetGenerator.kt @@ -56,8 +56,7 @@ class VectorAssetGenerator( // Kotlin 1.4) each property with the same name will be considered as a possible candidate // for resolution, regardless of the access modifier, so by using unique names we reduce // the size from ~6000 to 1, and speed up compilation time for these icons. - @OptIn(ExperimentalStdlibApi::class) - val backingPropertyName = "_" + iconName.decapitalize(Locale.ROOT) + val backingPropertyName = "_" + iconName.replaceFirstChar { it.lowercase(Locale.ROOT) } val backingProperty = backingPropertySpec(name = backingPropertyName, ClassNames.ImageVector) val generation = FileSpec.builder( diff --git a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt index 9b160b48..8f632b4b 100644 --- a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt +++ b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt @@ -7,6 +7,7 @@ import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.MemberName import java.io.File import java.util.* +import kotlin.io.path.createTempDirectory typealias IconNameTransformer = (iconName: String, group: String) -> String @@ -47,9 +48,9 @@ object Svg2Compose { // if there is no previous group, this is the root dir, and the group name should be the accessorName val groupName = if (previousGroup == null) accessorName else file.name.toKotlinPropertyName() - val groupPackage = previousGroup?.let { group -> "${group.groupPackage}.${group.groupName.second.toLowerCase()}" } - ?: "$applicationIconPackage" - val iconsPackage = "$groupPackage.${groupName.toLowerCase()}" + val groupPackage = previousGroup?.let { group -> "${group.groupPackage}.${group.groupName.second.lowercase()}" } + ?: applicationIconPackage + val iconsPackage = "$groupPackage.${groupName.lowercase()}" val (groupFileSpec, groupClassName) = IconGroupGenerator( groupPackage, @@ -96,7 +97,7 @@ object Svg2Compose { memberNames.first { it.simpleName == entry.value.kotlinName } } } else { - emptyMap() + emptyMap() } val result = GeneratedGroup( @@ -141,7 +142,7 @@ object Svg2Compose { return groupStack.pop().asParsingResult() } - private fun drawableTempDirectory() = createTempDir(suffix = "svg2compose/") + private fun drawableTempDirectory() = createTempDirectory(prefix = "svg2compose").toFile() private val String.withoutExtension get() = substringBeforeLast(".") } diff --git a/src/test/kotlin/TestMain.kt b/src/test/kotlin/TestMain.kt index 6836fa9e..d0b46dc9 100644 --- a/src/test/kotlin/TestMain.kt +++ b/src/test/kotlin/TestMain.kt @@ -35,10 +35,34 @@ class TestMain { "Icons weren't generated" } + + var requiredIcons = mutableListOf() + + iconsDir.walkTopDown().onEnter { it -> + if (it.isFile && it.isPlausibleIcon) { + requiredIcons.add(it.path.camelCase) + true + } else false + } + + val generatedIcons = mutableListOf() + destinationDir.walkTopDown().onEnter { it -> + if (it.isFile) { + generatedIcons.add(it) + true + } else false + + } + + assertEquals(requiredIcons.size, generatedIcons.size, "Error generating all icons.") + destinationDir.deleteRecursively() } + val File.isPlausibleIcon + get() = extension.lowercase() == "xml" || extension.lowercase() == "svg" + private fun String.removeSuffix(suffix: String, ignoreCase: Boolean): String { return if (ignoreCase) { val index = lastIndexOf(suffix, ignoreCase = true) @@ -56,6 +80,7 @@ class TestMain { assertEquals(iconName, "icon-name".camelCase) assertEquals(iconName, "icon name".camelCase) assertEquals(iconName, "icon_name".camelCase) + } val String.camelCase: String From 473dea0eca2e08673decdb5ff70cc24b5c12a51d Mon Sep 17 00:00:00 2001 From: brymher Date: Sun, 20 Mar 2022 01:52:15 +0300 Subject: [PATCH 4/8] Initial custom size support --- .../material/icons/generator/IconWriter.kt | 19 +++++++++++++++++-- .../material/icons/generator/vector/Vector.kt | 9 +++++---- .../com/devsrsouza/svg2compose/Svg2Compose.kt | 4 +++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt b/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt index e360ff9c..9a14fde6 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt @@ -16,7 +16,6 @@ package androidx.compose.material.icons.generator -import br.com.devsrsouza.svg2compose.IconNameTransformer import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.MemberName import java.io.File @@ -32,6 +31,7 @@ class IconWriter( private val icons: Collection, private val groupClass: ClassName, private val groupPackage: String, + private val defaultSize: Int?, ) { /** * Generates icons and writes them to [outputSrcDirectory], using [iconNamePredicate] to @@ -55,7 +55,22 @@ class IconWriter( }.map { icon -> val iconName = icon.kotlinName - val vector = IconParser(icon).parse() + val vector = IconParser(icon).parse().let { parsedVector -> + defaultSize?.let { + parsedVector.copy( + width = when (parsedVector.width) { + is Pixel -> Pixel(defaultSize.toFloat()) + is Dp -> Dp(defaultSize.toFloat()) + }, + height = when (parsedVector.width) { + is Pixel -> Pixel(defaultSize.toFloat()) + is Dp -> Dp(defaultSize.toFloat()) + }, + viewportWidth = defaultSize.toFloat(), + viewportHeight = defaultSize.toFloat() + ) + } ?: parsedVector + } val (fileSpec, accessProperty) = VectorAssetGenerator( iconName, diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/vector/Vector.kt b/src/main/kotlin/androidx/compose/material/icons/generator/vector/Vector.kt index 4c57ffdd..a5a77cb6 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/vector/Vector.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/vector/Vector.kt @@ -25,7 +25,7 @@ import java.awt.LinearGradientPaint * [nodes] may either be a singleton list of the root group, or a list of root paths / groups if * there are multiple top level declaration. */ -class Vector( +data class Vector( val width: GraphicUnit, val height: GraphicUnit, val viewportWidth: Float, @@ -60,12 +60,13 @@ sealed class Fill { val startX: Float, val endY: Float, val endX: Float, - val colorStops: MutableList> = mutableListOf() + val colorStops: MutableList> = mutableListOf() ) : Fill() + data class RadialGradient( val gradientRadius: Float, val centerX: Float, val centerY: Float, - val colorStops: MutableList> = mutableListOf() - ): Fill() + val colorStops: MutableList> = mutableListOf() + ) : Fill() } \ No newline at end of file diff --git a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt index 8f632b4b..ddc94cd6 100644 --- a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt +++ b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt @@ -28,7 +28,8 @@ object Svg2Compose { vectorsDirectory: File, type: VectorType = VectorType.SVG, iconNameTransformer: IconNameTransformer = { it, _ -> it }, - allAssetsPropertyName: String = "AllAssets" + allAssetsPropertyName: String = "AllAssets", + defaultSize: Int?, ): ParsingResult { fun nameRelative(vectorFile: File) = vectorFile.relativeTo(vectorsDirectory).path @@ -89,6 +90,7 @@ object Svg2Compose { icons.values, groupClassName, iconsPackage, + defaultSize ) val memberNames = writer.generateTo(outputSourceDirectory) { true } From cb75fbd7d77eaab0bd639a2c70d3663bfea4d9f6 Mon Sep 17 00:00:00 2001 From: brymher Date: Sun, 20 Mar 2022 02:01:13 +0300 Subject: [PATCH 5/8] Initial custom size support --- .../compose/material/icons/generator/IconWriter.kt | 9 ++++++--- .../kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt | 2 +- src/test/kotlin/TestMain.kt | 8 ++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt b/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt index 9a14fde6..7f0696c6 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt @@ -55,8 +55,10 @@ class IconWriter( }.map { icon -> val iconName = icon.kotlinName + /**check [androidx.compose.material.icons.generator.vector.Vector]**/ val vector = IconParser(icon).parse().let { parsedVector -> defaultSize?.let { + /*THE WHEN IS JUST TO BE SAFE ABOUT IT*/ parsedVector.copy( width = when (parsedVector.width) { is Pixel -> Pixel(defaultSize.toFloat()) @@ -65,9 +67,7 @@ class IconWriter( height = when (parsedVector.width) { is Pixel -> Pixel(defaultSize.toFloat()) is Dp -> Dp(defaultSize.toFloat()) - }, - viewportWidth = defaultSize.toFloat(), - viewportHeight = defaultSize.toFloat() + } ) } ?: parsedVector } @@ -81,6 +81,9 @@ class IconWriter( fileSpec.writeTo(outputSrcDirectory) MemberName(fileSpec.packageName, accessProperty) + } + } + } diff --git a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt index ddc94cd6..943ebdbe 100644 --- a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt +++ b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt @@ -29,7 +29,7 @@ object Svg2Compose { type: VectorType = VectorType.SVG, iconNameTransformer: IconNameTransformer = { it, _ -> it }, allAssetsPropertyName: String = "AllAssets", - defaultSize: Int?, + defaultSize: Int? = null, ): ParsingResult { fun nameRelative(vectorFile: File) = vectorFile.relativeTo(vectorsDirectory).path diff --git a/src/test/kotlin/TestMain.kt b/src/test/kotlin/TestMain.kt index d0b46dc9..17da11bd 100644 --- a/src/test/kotlin/TestMain.kt +++ b/src/test/kotlin/TestMain.kt @@ -26,7 +26,8 @@ class TestMain { vectorsDirectory = iconsDir, iconNameTransformer = { name, group -> name.removeSuffix(group, ignoreCase = true) - } + }, + defaultSize = 24 ) val generatedIconsDir = File(destinationDir, "br/com/compose/icons") @@ -35,8 +36,7 @@ class TestMain { "Icons weren't generated" } - - var requiredIcons = mutableListOf() + val requiredIcons = mutableListOf() iconsDir.walkTopDown().onEnter { it -> if (it.isFile && it.isPlausibleIcon) { @@ -56,7 +56,7 @@ class TestMain { assertEquals(requiredIcons.size, generatedIcons.size, "Error generating all icons.") - destinationDir.deleteRecursively() + // destinationDir.deleteRecursively() } From 26c578b7995218d0a13b269e35f8e032f3bccdde Mon Sep 17 00:00:00 2001 From: brymher Date: Sun, 20 Mar 2022 03:04:42 +0300 Subject: [PATCH 6/8] Added actual scaling down of the icons: Works with test icons. NOT TESTED FURTHER --- .../material/icons/generator/IconParser.kt | 33 +++-- .../material/icons/generator/IconWriter.kt | 16 +-- .../icons/generator/vector/PathNode.kt | 136 ++++++++++-------- .../icons/generator/vector/PathParser.kt | 5 +- .../com/devsrsouza/svg2compose/Svg2Compose.kt | 9 +- src/test/kotlin/TestMain.kt | 2 +- 6 files changed, 113 insertions(+), 88 deletions(-) diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/IconParser.kt b/src/main/kotlin/androidx/compose/material/icons/generator/IconParser.kt index 3b10bdc7..d7f16a81 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/IconParser.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/IconParser.kt @@ -1,4 +1,3 @@ - /* * Copyright 2020 The Android Open Source Project * @@ -18,13 +17,16 @@ package androidx.compose.material.icons.generator import androidx.compose.material.icons.generator.vector.* +import br.com.devsrsouza.svg2compose.Size import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser.END_DOCUMENT import org.xmlpull.v1.XmlPullParser.END_TAG import org.xmlpull.v1.XmlPullParser.START_TAG import org.xmlpull.v1.XmlPullParserException import org.xmlpull.v1.XmlPullParserFactory -import kotlin.math.log10 + + +data class ScaleFactor(val x: Float = 1f, val y: Float = 1f) /** * Parser that converts [icon]s into [Vector]s @@ -34,7 +36,7 @@ class IconParser(private val icon: Icon) { /** * @return a [Vector] representing the provided [icon]. */ - fun parse(): Vector { + fun parse(defaultSize: Size? = null): Vector { val parser = XmlPullParserFactory.newInstance().newPullParser().apply { setInput(icon.fileContent.byteInputStream(), null) seekToStartTag() @@ -47,6 +49,13 @@ class IconParser(private val icon: Icon) { val viewportWidth = parser.getAttributeValue(null, VIEWPORT_WIDTH).toFloat() val viewportHeight = parser.getAttributeValue(null, VIEWPORT_HEIGHT).toFloat() + val scale = defaultSize?.let { requestedSize -> + ScaleFactor( + requestedSize.width / viewportWidth, + requestedSize.height / viewportHeight + ) + } ?: ScaleFactor() + parser.next() val nodes = mutableListOf() @@ -98,7 +107,7 @@ class IconParser(private val icon: Icon) { strokeLineJoin = strokeJoin ?: StrokeJoin.Miter, strokeLineMiter = strokeMiterLimit ?: 4.0f, fillType = fillType, - nodes = PathParser.parsePathString(pathData) + nodes = PathParser.parsePathString(pathData, scale) ) if (currentGroup != null) { currentGroup.paths.add(path) @@ -115,7 +124,7 @@ class IconParser(private val icon: Icon) { CLIP_PATH -> { /* TODO: b/147418351 - parse clipping paths */ } GRADIENT -> { - val gradient = when (parser.getAttributeValue(null, TYPE)){ + val gradient = when (parser.getAttributeValue(null, TYPE)) { LINEAR -> { val startX = parser.getValueAsFloat(START_X) ?: 0f val startY = parser.getValueAsFloat(START_Y) ?: 0f @@ -142,8 +151,8 @@ class IconParser(private val icon: Icon) { } val lastPath = currentGroup?.paths?.removeLast() ?: nodes.removeLast() - if (lastPath as? VectorNode.Path != null && lastPath.fill == null){ - val gradientPath = lastPath.copy (fill = gradient) + if (lastPath as? VectorNode.Path != null && lastPath.fill == null) { + val gradientPath = lastPath.copy(fill = gradient) if (currentGroup != null) { currentGroup.paths.add(gradientPath) } else { @@ -155,9 +164,9 @@ class IconParser(private val icon: Icon) { val offset = parser.getValueAsFloat(OFFSET) ?: 0f val colorHex = parser.getAttributeValue(null, COLOR).toHexColor() - val colorStop = Pair(offset,colorHex) + val colorStop = Pair(offset, colorHex) val lastPath = (currentGroup?.paths?.last() ?: nodes.last()) as? VectorNode.Path - when (lastPath?.fill){ + when (lastPath?.fill) { is Fill.LinearGradient -> lastPath.fill.colorStops.add(colorStop) is Fill.RadialGradient -> lastPath.fill.colorStops.add(colorStop) else -> {} @@ -172,8 +181,8 @@ class IconParser(private val icon: Icon) { return Vector( width, height, - viewportWidth, - viewportHeight, + viewportWidth * scale.x, + viewportHeight * scale.y, nodes ) } @@ -205,7 +214,7 @@ private val hexRegex = "^[0-9a-fA-F]{6,8}".toRegex() private fun String.toHexColor(): String { return removePrefix("#") .let { - if(hexRegex.matches(it)) { + if (hexRegex.matches(it)) { if (it.length > 6) it else "FF$it" } else { diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt b/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt index 7f0696c6..3922a56e 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt @@ -16,6 +16,7 @@ package androidx.compose.material.icons.generator +import br.com.devsrsouza.svg2compose.Size import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.MemberName import java.io.File @@ -31,7 +32,7 @@ class IconWriter( private val icons: Collection, private val groupClass: ClassName, private val groupPackage: String, - private val defaultSize: Int?, + private val defaultSize: Size?, ) { /** * Generates icons and writes them to [outputSrcDirectory], using [iconNamePredicate] to @@ -56,17 +57,16 @@ class IconWriter( val iconName = icon.kotlinName /**check [androidx.compose.material.icons.generator.vector.Vector]**/ - val vector = IconParser(icon).parse().let { parsedVector -> + val vector = IconParser(icon).parse(defaultSize).let { parsedVector -> defaultSize?.let { - /*THE WHEN IS JUST TO BE SAFE ABOUT IT*/ parsedVector.copy( width = when (parsedVector.width) { - is Pixel -> Pixel(defaultSize.toFloat()) - is Dp -> Dp(defaultSize.toFloat()) + is Pixel -> Pixel(defaultSize.width) + is Dp -> Dp(defaultSize.width) }, - height = when (parsedVector.width) { - is Pixel -> Pixel(defaultSize.toFloat()) - is Dp -> Dp(defaultSize.toFloat()) + height = when (parsedVector.height) { + is Pixel -> Pixel(defaultSize.height) + is Dp -> Dp(defaultSize.height) } ) } ?: parsedVector diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/vector/PathNode.kt b/src/main/kotlin/androidx/compose/material/icons/generator/vector/PathNode.kt index 325a45e2..4a2671d7 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/vector/PathNode.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/vector/PathNode.kt @@ -16,6 +16,9 @@ package androidx.compose.material.icons.generator.vector +import androidx.compose.material.icons.generator.ScaleFactor +import com.google.common.math.Quantiles.Scale + /** * Class representing a singular path command in a vector. * @@ -39,6 +42,7 @@ sealed class PathNode(val isCurve: Boolean = false, val isQuad: Boolean = false) data class RelativeMoveTo(val x: Float, val y: Float) : PathNode() { override fun asFunctionCall() = "moveToRelative(${x}f, ${y}f)" } + data class MoveTo(val x: Float, val y: Float) : PathNode() { override fun asFunctionCall() = "moveTo(${x}f, ${y}f)" } @@ -46,6 +50,7 @@ sealed class PathNode(val isCurve: Boolean = false, val isQuad: Boolean = false) data class RelativeLineTo(val x: Float, val y: Float) : PathNode() { override fun asFunctionCall() = "lineToRelative(${x}f, ${y}f)" } + data class LineTo(val x: Float, val y: Float) : PathNode() { override fun asFunctionCall() = "lineTo(${x}f, ${y}f)" } @@ -53,6 +58,7 @@ sealed class PathNode(val isCurve: Boolean = false, val isQuad: Boolean = false) data class RelativeHorizontalTo(val x: Float) : PathNode() { override fun asFunctionCall() = "horizontalLineToRelative(${x}f)" } + data class HorizontalTo(val x: Float) : PathNode() { override fun asFunctionCall() = "horizontalLineTo(${x}f)" } @@ -60,6 +66,7 @@ sealed class PathNode(val isCurve: Boolean = false, val isQuad: Boolean = false) data class RelativeVerticalTo(val y: Float) : PathNode() { override fun asFunctionCall() = "verticalLineToRelative(${y}f)" } + data class VerticalTo(val y: Float) : PathNode() { override fun asFunctionCall() = "verticalLineTo(${y}f)" } @@ -145,7 +152,8 @@ sealed class PathNode(val isCurve: Boolean = false, val isQuad: Boolean = false) val arcStartDx: Float, val arcStartDy: Float ) : PathNode() { - override fun asFunctionCall() = "arcToRelative(${horizontalEllipseRadius}f, ${verticalEllipseRadius}f, ${theta}f, $isMoreThanHalf, $isPositiveArc, ${arcStartDx}f, ${arcStartDy}f)" + override fun asFunctionCall() = + "arcToRelative(${horizontalEllipseRadius}f, ${verticalEllipseRadius}f, ${theta}f, $isMoreThanHalf, $isPositiveArc, ${arcStartDx}f, ${arcStartDy}f)" } data class ArcTo( @@ -157,7 +165,8 @@ sealed class PathNode(val isCurve: Boolean = false, val isQuad: Boolean = false) val arcStartX: Float, val arcStartY: Float ) : PathNode() { - override fun asFunctionCall() = "arcTo(${horizontalEllipseRadius}f, ${verticalEllipseRadius}f, ${theta}f, $isMoreThanHalf, $isPositiveArc, ${arcStartX}f, ${arcStartY}f)" + override fun asFunctionCall() = + "arcTo(${horizontalEllipseRadius}f, ${verticalEllipseRadius}f, ${theta}f, $isMoreThanHalf, $isPositiveArc, ${arcStartX}f, ${arcStartY}f)" } } /* ktlint-enable max-line-length */ @@ -168,7 +177,7 @@ sealed class PathNode(val isCurve: Boolean = false, val isQuad: Boolean = false) * @return [PathNode] that matches the key * @throws IllegalArgumentException */ -internal fun Char.toPathNodes(args: FloatArray): List = when (this) { +internal fun Char.toPathNodes(args: FloatArray, scale: ScaleFactor = ScaleFactor()): List = when (this) { RelativeCloseKey, CloseKey -> listOf( PathNode.Close ) @@ -177,8 +186,8 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_MOVE_TO_ARGS ) { array -> PathNode.RelativeMoveTo( - x = array[0], - y = array[1] + x = array[0] * scale.x, + y = array[1] * scale.y ) } @@ -187,8 +196,8 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_MOVE_TO_ARGS ) { array -> PathNode.MoveTo( - x = array[0], - y = array[1] + x = array[0] * scale.x, + y = array[1] * scale.y ) } @@ -197,8 +206,8 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_LINE_TO_ARGS ) { array -> PathNode.RelativeLineTo( - x = array[0], - y = array[1] + x = array[0] * scale.x, + y = array[1] * scale.y ) } @@ -207,8 +216,8 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_LINE_TO_ARGS ) { array -> PathNode.LineTo( - x = array[0], - y = array[1] + x = array[0] * scale.x, + y = array[1] * scale.y ) } @@ -217,7 +226,7 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_HORIZONTAL_TO_ARGS ) { array -> PathNode.RelativeHorizontalTo( - x = array[0] + x = array[0] * scale.x ) } @@ -225,21 +234,21 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { args, NUM_HORIZONTAL_TO_ARGS ) { array -> - PathNode.HorizontalTo(x = array[0]) + PathNode.HorizontalTo(x = array[0] * scale.x) } RelativeVerticalToKey -> pathNodesFromArgs( args, NUM_VERTICAL_TO_ARGS ) { array -> - PathNode.RelativeVerticalTo(y = array[0]) + PathNode.RelativeVerticalTo(y = array[0] * scale.y) } VerticalToKey -> pathNodesFromArgs( args, NUM_VERTICAL_TO_ARGS ) { array -> - PathNode.VerticalTo(y = array[0]) + PathNode.VerticalTo(y = array[0] * scale.y) } RelativeCurveToKey -> pathNodesFromArgs( @@ -247,12 +256,12 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_CURVE_TO_ARGS ) { array -> PathNode.RelativeCurveTo( - dx1 = array[0], - dy1 = array[1], - dx2 = array[2], - dy2 = array[3], - dx3 = array[4], - dy3 = array[5] + dx1 = array[0] * scale.x, + dy1 = array[1] * scale.y, + dx2 = array[2] * scale.x, + dy2 = array[3] * scale.y, + dx3 = array[4] * scale.x, + dy3 = array[5] * scale.y ) } @@ -261,12 +270,12 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_CURVE_TO_ARGS ) { array -> PathNode.CurveTo( - x1 = array[0], - y1 = array[1], - x2 = array[2], - y2 = array[3], - x3 = array[4], - y3 = array[5] + x1 = array[0] * scale.x, + y1 = array[1] * scale.y, + x2 = array[2] * scale.x, + y2 = array[3] * scale.y, + x3 = array[4] * scale.x, + y3 = array[5] * scale.y ) } @@ -275,10 +284,10 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_REFLECTIVE_CURVE_TO_ARGS ) { array -> PathNode.RelativeReflectiveCurveTo( - x1 = array[0], - y1 = array[1], - x2 = array[2], - y2 = array[3] + x1 = array[0] * scale.x, + y1 = array[1] * scale.y, + x2 = array[2] * scale.x, + y2 = array[3] * scale.y ) } @@ -287,10 +296,10 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_REFLECTIVE_CURVE_TO_ARGS ) { array -> PathNode.ReflectiveCurveTo( - x1 = array[0], - y1 = array[1], - x2 = array[2], - y2 = array[3] + x1 = array[0] * scale.x, + y1 = array[1] * scale.y, + x2 = array[2] * scale.x, + y2 = array[3] * scale.y ) } @@ -299,10 +308,10 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_QUAD_TO_ARGS ) { array -> PathNode.RelativeQuadTo( - x1 = array[0], - y1 = array[1], - x2 = array[2], - y2 = array[3] + x1 = array[0] * scale.x, + y1 = array[1] * scale.y, + x2 = array[2] * scale.x, + y2 = array[3] * scale.y ) } @@ -311,10 +320,10 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_QUAD_TO_ARGS ) { array -> PathNode.QuadTo( - x1 = array[0], - y1 = array[1], - x2 = array[2], - y2 = array[3] + x1 = array[0] * scale.x, + y1 = array[1] * scale.y, + x2 = array[2] * scale.x, + y2 = array[3] * scale.y ) } @@ -323,8 +332,8 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_REFLECTIVE_QUAD_TO_ARGS ) { array -> PathNode.RelativeReflectiveQuadTo( - x = array[0], - y = array[1] + x = array[0] * scale.x, + y = array[1] * scale.y ) } @@ -333,8 +342,8 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_REFLECTIVE_QUAD_TO_ARGS ) { array -> PathNode.ReflectiveQuadTo( - x = array[0], - y = array[1] + x = array[0] * scale.x, + y = array[1] * scale.y ) } @@ -343,13 +352,13 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_ARC_TO_ARGS ) { array -> PathNode.RelativeArcTo( - horizontalEllipseRadius = array[0], - verticalEllipseRadius = array[1], + horizontalEllipseRadius = array[0] * scale.x, + verticalEllipseRadius = array[1] * scale.y, theta = array[2], - isMoreThanHalf = array[3].compareTo(0.0f) != 0, - isPositiveArc = array[4].compareTo(0.0f) != 0, - arcStartDx = array[5], - arcStartDy = array[6] + isMoreThanHalf = (array[3] * scale.x).compareTo(0.0f) != 0, + isPositiveArc = (array[4] * scale.y).compareTo(0.0f) != 0, + arcStartDx = array[5] * scale.x, + arcStartDy = array[6] * scale.y ) } @@ -358,13 +367,13 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { NUM_ARC_TO_ARGS ) { array -> PathNode.ArcTo( - horizontalEllipseRadius = array[0], - verticalEllipseRadius = array[1], + horizontalEllipseRadius = array[0] * scale.x, + verticalEllipseRadius = array[1] * scale.y, theta = array[2], - isMoreThanHalf = array[3].compareTo(0.0f) != 0, - isPositiveArc = array[4].compareTo(0.0f) != 0, - arcStartX = array[5], - arcStartY = array[6] + isMoreThanHalf = (array[3] * scale.x).compareTo(0.0f) != 0, + isPositiveArc = (array[4] * scale.y).compareTo(0.0f) != 0, + arcStartX = array[5] * scale.x, + arcStartY = array[6] * scale.y ) } @@ -374,6 +383,7 @@ internal fun Char.toPathNodes(args: FloatArray): List = when (this) { private inline fun pathNodesFromArgs( args: FloatArray, numArgs: Int, + scale: ScaleFactor = ScaleFactor(), nodeFor: (subArray: FloatArray) -> PathNode ): List { return (0..args.size - numArgs step numArgs).map { index -> @@ -383,13 +393,13 @@ private inline fun pathNodesFromArgs( // According to the spec, if a MoveTo is followed by multiple pairs of coordinates, // the subsequent pairs are treated as implicit corresponding LineTo commands. node is PathNode.MoveTo && index > 0 -> PathNode.LineTo( - subArray[0], - subArray[1] + subArray[0] * scale.x, + subArray[1] * scale.y ) node is PathNode.RelativeMoveTo && index > 0 -> PathNode.RelativeLineTo( - subArray[0], - subArray[1] + subArray[0] * scale.x, + subArray[1] * scale.y ) else -> node } diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/vector/PathParser.kt b/src/main/kotlin/androidx/compose/material/icons/generator/vector/PathParser.kt index e004a05f..9cd23ac4 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/vector/PathParser.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/vector/PathParser.kt @@ -16,6 +16,7 @@ package androidx.compose.material.icons.generator.vector +import androidx.compose.material.icons.generator.ScaleFactor import kotlin.math.min /** @@ -28,11 +29,11 @@ object PathParser { * arguments * throws an IllegalArgumentException or NumberFormatException if the parameters are invalid */ - fun parsePathString(pathData: String): List { + fun parsePathString(pathData: String, scale: ScaleFactor = ScaleFactor()): List { val nodes = mutableListOf() fun addNode(cmd: Char, args: FloatArray) { - nodes.addAll(cmd.toPathNodes(args)) + nodes.addAll(cmd.toPathNodes(args, scale)) } var start = 0 diff --git a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt index 943ebdbe..c2e38689 100644 --- a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt +++ b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt @@ -11,6 +11,11 @@ import kotlin.io.path.createTempDirectory typealias IconNameTransformer = (iconName: String, group: String) -> String +data class Size(val height: Float, val width: Float) { + constructor(size: Float) : this(size, size) + constructor(size: Int) : this(size.toFloat()) +} + object Svg2Compose { /** @@ -29,7 +34,7 @@ object Svg2Compose { type: VectorType = VectorType.SVG, iconNameTransformer: IconNameTransformer = { it, _ -> it }, allAssetsPropertyName: String = "AllAssets", - defaultSize: Int? = null, + size: Size? = null, ): ParsingResult { fun nameRelative(vectorFile: File) = vectorFile.relativeTo(vectorsDirectory).path @@ -90,7 +95,7 @@ object Svg2Compose { icons.values, groupClassName, iconsPackage, - defaultSize + size ) val memberNames = writer.generateTo(outputSourceDirectory) { true } diff --git a/src/test/kotlin/TestMain.kt b/src/test/kotlin/TestMain.kt index 17da11bd..2fa13b1c 100644 --- a/src/test/kotlin/TestMain.kt +++ b/src/test/kotlin/TestMain.kt @@ -27,7 +27,7 @@ class TestMain { iconNameTransformer = { name, group -> name.removeSuffix(group, ignoreCase = true) }, - defaultSize = 24 + size = Size(24) ) val generatedIconsDir = File(destinationDir, "br/com/compose/icons") From f31948e3c7b8b51de427aa706a194d6e2f82062b Mon Sep 17 00:00:00 2001 From: brymher Date: Sun, 20 Mar 2022 03:20:42 +0300 Subject: [PATCH 7/8] Added Icon size to the icon name i.e. Wifi24.kt --- .../compose/material/icons/generator/IconWriter.kt | 4 +++- .../br/com/devsrsouza/svg2compose/Svg2Compose.kt | 10 +++++++++- src/test/kotlin/TestMain.kt | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt b/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt index 3922a56e..d5fe131e 100644 --- a/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt +++ b/src/main/kotlin/androidx/compose/material/icons/generator/IconWriter.kt @@ -73,7 +73,9 @@ class IconWriter( } val (fileSpec, accessProperty) = VectorAssetGenerator( - iconName, + defaultSize?.let { + "$iconName${it.maxValue}" + } ?: iconName, groupPackage, vector ).createFileSpec(groupClass) diff --git a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt index c2e38689..ec3d0df3 100644 --- a/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt +++ b/src/main/kotlin/br/com/devsrsouza/svg2compose/Svg2Compose.kt @@ -8,12 +8,16 @@ import com.squareup.kotlinpoet.MemberName import java.io.File import java.util.* import kotlin.io.path.createTempDirectory +import kotlin.math.max typealias IconNameTransformer = (iconName: String, group: String) -> String data class Size(val height: Float, val width: Float) { constructor(size: Float) : this(size, size) constructor(size: Int) : this(size.toFloat()) + + val maxValue + get() = max(height, width).toInt() } object Svg2Compose { @@ -101,7 +105,11 @@ object Svg2Compose { val memberNames = writer.generateTo(outputSourceDirectory) { true } icons.mapValues { entry -> - memberNames.first { it.simpleName == entry.value.kotlinName } + memberNames.first { + val name = (size?.let { setSize -> "${entry.value.kotlinName}${setSize.maxValue}" } + ?: entry.value.kotlinName) + it.simpleName == name + } } } else { emptyMap() diff --git a/src/test/kotlin/TestMain.kt b/src/test/kotlin/TestMain.kt index 2fa13b1c..15a04363 100644 --- a/src/test/kotlin/TestMain.kt +++ b/src/test/kotlin/TestMain.kt @@ -46,6 +46,7 @@ class TestMain { } val generatedIcons = mutableListOf() + destinationDir.walkTopDown().onEnter { it -> if (it.isFile) { generatedIcons.add(it) @@ -54,7 +55,7 @@ class TestMain { } - assertEquals(requiredIcons.size, generatedIcons.size, "Error generating all icons.") + // assertEquals(requiredIcons.size, generatedIcons.size, "Error generating all icons.") // destinationDir.deleteRecursively() From 0827b7f21316b745ce0a5f0dab7a0b482e6c9c7e Mon Sep 17 00:00:00 2001 From: brymher Date: Sun, 20 Mar 2022 03:50:21 +0300 Subject: [PATCH 8/8] Added Visual tests: Delete and generate preferred sizes again --- build.gradle.kts | 12 +++++ settings.gradle.kts | 7 +++ src/test/kotlin/EmojiTest.kt | 21 --------- src/test/kotlin/Main.kt | 28 ------------ src/test/kotlin/TestMain.kt | 11 +++-- src/test/kotlin/ui/Main.kt | 63 ++++++++++++++++++++++++++ src/test/kotlin/ui/theme/AppTheme.kt | 25 ++++++++++ src/test/kotlin/ui/theme/Colors.kt | 40 ++++++++++++++++ src/test/kotlin/ui/theme/Typography.kt | 22 +++++++++ 9 files changed, 175 insertions(+), 54 deletions(-) delete mode 100644 src/test/kotlin/EmojiTest.kt delete mode 100644 src/test/kotlin/Main.kt create mode 100644 src/test/kotlin/ui/Main.kt create mode 100644 src/test/kotlin/ui/theme/AppTheme.kt create mode 100644 src/test/kotlin/ui/theme/Colors.kt create mode 100644 src/test/kotlin/ui/theme/Typography.kt diff --git a/build.gradle.kts b/build.gradle.kts index 042e4c2f..02bcb0c4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") version "1.6.10" + id("org.jetbrains.compose") version "1.1.1" id("maven-publish") } @@ -10,11 +11,17 @@ version = "0.7.0" repositories { mavenCentral() + google() + mavenCentral() + maven("https://jitpack.io") maven("https://maven.google.com") maven("https://jetbrains.bintray.com/trove4j") + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") } dependencies { + val composeVersion = "1.1.1" + implementation("com.google.guava:guava:31.1-jre") implementation("com.android.tools:sdk-common:27.2.0-alpha16") implementation("com.android.tools:common:27.2.0-alpha16") @@ -22,6 +29,11 @@ dependencies { implementation("org.ogce:xpp3:1.1.6") testImplementation(kotlin("test-junit")) + implementation("org.jetbrains.compose.ui:ui:$composeVersion") + implementation("org.jetbrains.compose.runtime:runtime:$composeVersion") + implementation("org.jetbrains.compose.foundation:foundation:$composeVersion") + implementation(compose.desktop.currentOs) + } tasks.test { diff --git a/settings.gradle.kts b/settings.gradle.kts index 6cec84dc..b0ddcdc4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,10 @@ +pluginManagement { + repositories { + google() + gradlePluginPortal() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + } +} rootProject.name = "svg-to-compose" diff --git a/src/test/kotlin/EmojiTest.kt b/src/test/kotlin/EmojiTest.kt deleted file mode 100644 index df958e87..00000000 --- a/src/test/kotlin/EmojiTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -package br.com.devsrsouza.svg2compose - -import java.io.File - - -fun main(){ - val iconTest = File("/Users/marioferreiravilanova/Documents/Workspace/kotlin/svg-to-compose/src/test/icons") - val src = File("/Users/marioferreiravilanova/Documents/Workspace/kotlin/svg-to-compose/src/test/results").apply { mkdirs() } - - Svg2Compose.parse( - applicationIconPackage = "com.test", - accessorName = "Icons", - outputSourceDirectory = src, - vectorsDirectory = iconTest, - type = VectorType.SVG, - iconNameTransformer = { name, group -> - name.split("-").joinToString(separator = "").removePrefix(group) - }, - allAssetsPropertyName = "AllIcons" - ) -} diff --git a/src/test/kotlin/Main.kt b/src/test/kotlin/Main.kt deleted file mode 100644 index 936894fb..00000000 --- a/src/test/kotlin/Main.kt +++ /dev/null @@ -1,28 +0,0 @@ -package br.com.devsrsouza.svg2compose - -import java.io.File - -fun main() { - val iconTest = File("raw-icons4") - val src = File("build/generated-icons").apply { mkdirs() } - - Svg2Compose.parse( - applicationIconPackage = "br.com.compose.icons", - accessorName = "EvaIcons", - outputSourceDirectory = src, - vectorsDirectory = iconTest, - iconNameTransformer = { name, group -> - name.removeSuffix(group, ignoreCase = true) - } - ) -} - -private fun String.removeSuffix(suffix: String, ignoreCase: Boolean): String { - return if (ignoreCase) { - val index = lastIndexOf(suffix, ignoreCase = true) - - if (index > -1) substring(0, index) else this - } else { - removeSuffix(suffix) - } -} \ No newline at end of file diff --git a/src/test/kotlin/TestMain.kt b/src/test/kotlin/TestMain.kt index 15a04363..a748dac2 100644 --- a/src/test/kotlin/TestMain.kt +++ b/src/test/kotlin/TestMain.kt @@ -1,5 +1,6 @@ package br.com.devsrsouza.svg2compose +import androidx.compose.ui.window.application import org.junit.Test import java.io.File import kotlin.test.assertEquals @@ -9,7 +10,7 @@ class TestMain { @Test fun traverseGeneratorTest() { val iconsDir = File("src/test/resources/icons") - val destinationDir = File("src/test/resources/generated").apply { mkdirs() } + val destinationDir = File("src/test/kotlin/").apply { mkdirs() } assert(iconsDir.exists()) { "Make sure to add icons into res dir. Default test icons have been provided" @@ -27,7 +28,7 @@ class TestMain { iconNameTransformer = { name, group -> name.removeSuffix(group, ignoreCase = true) }, - size = Size(24) + size = Size(640) ) val generatedIconsDir = File(destinationDir, "br/com/compose/icons") @@ -55,9 +56,7 @@ class TestMain { } - // assertEquals(requiredIcons.size, generatedIcons.size, "Error generating all icons.") - - // destinationDir.deleteRecursively() + assertEquals(requiredIcons.size, generatedIcons.size, "Error generating all icons.") } @@ -90,3 +89,5 @@ class TestMain { } } + + diff --git a/src/test/kotlin/ui/Main.kt b/src/test/kotlin/ui/Main.kt new file mode 100644 index 00000000..e11eecc1 --- /dev/null +++ b/src/test/kotlin/ui/Main.kt @@ -0,0 +1,63 @@ +package br.com.devsrsouza.svg2compose.ui + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.material.Icon +import androidx.compose.material.LocalContentColor +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application +import androidx.compose.ui.window.rememberWindowState +import br.com.compose.icons.EvaIcons +import br.com.compose.icons.evaicons.* + + +fun main() = application { + Window(::exitApplication, rememberWindowState(width = 1020.dp, height = 800.dp)) { + + CompositionLocalProvider(LocalContentColor provides MaterialTheme.colors.primary) { + Column { + Row { + Icon(EvaIcons.Branch12, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale12, "Icon of size 12") + } + + Row { + Icon(EvaIcons.Branch14, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale14, "Icon of size 12") + } + Row { + Icon(EvaIcons.Branch16, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale16, "Icon of size 12") + } + Row { + Icon(EvaIcons.Branch18, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale18, "Icon of size 12") + } + Row { + Icon(EvaIcons.Branch24, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale24, "Icon of size 12") + } + Row { + Icon(EvaIcons.Branch32, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale32, "Icon of size 12") + } + Row { + Icon(EvaIcons.Branch64, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale64, "Icon of size 12") + } + Row { + Icon(EvaIcons.Branch128, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale128, "Icon of size 12") + } + Row { + Icon(EvaIcons.Branch640, "Icon of size 12") + Icon(EvaIcons.IcBalanceScale640, "Icon of size 12") + } + } + } + + } +} diff --git a/src/test/kotlin/ui/theme/AppTheme.kt b/src/test/kotlin/ui/theme/AppTheme.kt new file mode 100644 index 00000000..85ca9f84 --- /dev/null +++ b/src/test/kotlin/ui/theme/AppTheme.kt @@ -0,0 +1,25 @@ +package br.com.devsrsouza.svg2compose.ui.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf + +val isDarkMode = mutableStateOf(false) + +@Composable +fun AppTheme(isDarkMode: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { + + val colors = if (isDarkMode) darkColors else lightColors + + val typography = if (isDarkMode) darkTypography else lightTypography + + MaterialTheme( + colors = colors, + typography = typography, + content = content + ) + +} + + diff --git a/src/test/kotlin/ui/theme/Colors.kt b/src/test/kotlin/ui/theme/Colors.kt new file mode 100644 index 00000000..5f873974 --- /dev/null +++ b/src/test/kotlin/ui/theme/Colors.kt @@ -0,0 +1,40 @@ +package br.com.devsrsouza.svg2compose.ui.theme + +import androidx.compose.material.darkColors +import androidx.compose.material.lightColors +import androidx.compose.ui.graphics.Color + + +val darkColors by lazy { + darkColors( + background = Color(0xFF1A091F), + onBackground = Color(0xFFC099CD), + surface = Color(0xFF1B0036),// Color(0xFF5200A4), + onSurface = Color(0xFFF9E3FF), + primary = Color(0xFF0A010D), + onPrimary = Color(0xFFF9E3FF), + primaryVariant = Color(0xFF1B0036), + secondary = Color(0xFF9F0037), + onSecondary = Color(0xFFDCB5C2), + secondaryVariant = Color(0xFF000000), + error = Color(0xFFFF0059), + onError = Color(0xFFDCB5C2) + ) +} + +val lightColors by lazy { + lightColors( + background = Color(0xFFF9E3FF), + onBackground = Color(0xFF1B0036), + surface = Color(0xFF004848), // Color(0xFF5200A4), + onSurface = Color(0xFFF9E3FF), + primary = Color(0xFFC099CD), + onPrimary = Color(0xFF1A091F), + primaryVariant = Color(0xFF1B0036), + secondary = Color(0xFF9F0037), + onSecondary = Color(0xFFDCB5C2), + secondaryVariant = Color(0xFF000000), + error = Color(0xFFFF0059), + onError = Color(0xFFDCB5C2) + ) +} \ No newline at end of file diff --git a/src/test/kotlin/ui/theme/Typography.kt b/src/test/kotlin/ui/theme/Typography.kt new file mode 100644 index 00000000..56a04993 --- /dev/null +++ b/src/test/kotlin/ui/theme/Typography.kt @@ -0,0 +1,22 @@ +package br.com.devsrsouza.svg2compose.ui.theme + +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Typography +import androidx.compose.runtime.Composable + +private var dark: Typography? = null +private var light: Typography? = null + +val darkTypography: Typography + @Composable get() = dark ?: MaterialTheme.typography.copy( + + ).also { + dark = it + } + +val lightTypography + @Composable get() = light ?: MaterialTheme.typography.copy( + + ).also { + light = it + } \ No newline at end of file