Skip to content

Commit 1d2233b

Browse files
committed
Parse gradient startColor/endColor
1 parent f46e683 commit 1d2233b

13 files changed

Lines changed: 1674 additions & 2 deletions

File tree

cli/src/test/kotlin/io/github/composegears/valkyrie/cli/SvgXmlToImageVectorCliTest.kt

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ class SvgXmlToImageVectorCliTest {
6565
),
6666
)
6767

68-
val files = tempDir.toFile().listFiles().orEmpty()
69-
assertThat(files.size).isEqualTo(11)
68+
val resultFiles = tempDir.toFile().listFiles().orEmpty().size
69+
val inputFiles = input.toFile().listFiles().orEmpty().size
70+
assertThat(resultFiles).isEqualTo(inputFiles)
7071
}
7172

7273
@ParameterizedTest
@@ -343,6 +344,28 @@ class SvgXmlToImageVectorCliTest {
343344
)
344345
}
345346

347+
@ParameterizedTest
348+
@MethodSource("testMatrix")
349+
fun `icon with compose colors and linear gradient`(arg: Pair<CliTestType, OutputFormat>) {
350+
arg.testConversion(
351+
inputResource = "imagevector/xml/ic_compose_color_linear_gradient.xml",
352+
expectedKtName = "ComposeColor.linear.gradient.kt",
353+
actualKtName = "ComposeColorLinearGradient.kt",
354+
useComposeColors = UseComposeColors(true),
355+
)
356+
}
357+
358+
@ParameterizedTest
359+
@MethodSource("testMatrix")
360+
fun `icon with compose colors and radial gradient`(arg: Pair<CliTestType, OutputFormat>) {
361+
arg.testConversion(
362+
inputResource = "imagevector/xml/ic_compose_color_radial_gradient.xml",
363+
expectedKtName = "ComposeColor.radial.gradient.kt",
364+
actualKtName = "ComposeColorRadialGradient.kt",
365+
useComposeColors = UseComposeColors(true),
366+
)
367+
}
368+
346369
@ParameterizedTest
347370
@MethodSource("testMatrix")
348371
fun `icon with transparent fill color`(arg: Pair<CliTestType, OutputFormat>) {

components/generator/imagevector/src/test/kotlin/io/github/composegears/valkyrie/generator/imagevector/XmlToImageVectorTest.kt

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
package io.github.composegears.valkyrie.generator.imagevector
22

3+
import assertk.assertFailure
34
import assertk.assertThat
5+
import assertk.assertions.hasMessage
46
import assertk.assertions.isEqualTo
7+
import assertk.assertions.isInstanceOf
58
import io.github.composegears.valkyrie.extensions.ResourceUtils.getResourcePath
69
import io.github.composegears.valkyrie.generator.imagevector.common.createConfig
710
import io.github.composegears.valkyrie.generator.imagevector.common.toResourceText
811
import io.github.composegears.valkyrie.parser.svgxml.SvgXmlParser
912
import io.github.composegears.valkyrie.parser.svgxml.util.IconType.XML
13+
import kotlin.io.path.Path
14+
import org.junit.jupiter.api.Test
1015
import org.junit.jupiter.params.ParameterizedTest
1116
import org.junit.jupiter.params.provider.EnumSource
1217

1318
class XmlToImageVectorTest {
1419

20+
@Test
21+
fun `broken icon path should throw exception`() {
22+
val brokenIconPath = Path("")
23+
24+
assertFailure {
25+
SvgXmlParser.toIrImageVector(brokenIconPath)
26+
}.isInstanceOf(IllegalStateException::class)
27+
.hasMessage(" must be an SVG or XML file.")
28+
}
29+
1530
@ParameterizedTest
1631
@EnumSource(value = OutputFormat::class)
1732
fun `generation without icon pack`(outputFormat: OutputFormat) {
@@ -186,6 +201,75 @@ class XmlToImageVectorTest {
186201
assertThat(output).isEqualTo(expected)
187202
}
188203

204+
@ParameterizedTest
205+
@EnumSource(value = OutputFormat::class)
206+
fun `icon with compose colors enabled`(outputFormat: OutputFormat) {
207+
val icon = getResourcePath("imagevector/xml/ic_compose_color.xml")
208+
val parserOutput = SvgXmlParser.toIrImageVector(icon)
209+
val output = ImageVectorGenerator.convert(
210+
vector = parserOutput.irImageVector,
211+
iconName = parserOutput.iconName,
212+
config = createConfig(
213+
packName = "ValkyrieIcons",
214+
outputFormat = outputFormat,
215+
useComposeColors = true,
216+
),
217+
).content
218+
219+
val expected = outputFormat.toResourceText(
220+
pathToBackingProperty = "imagevector/kt/backing/ComposeColor.kt",
221+
pathToLazyProperty = "imagevector/kt/lazy/ComposeColor.kt",
222+
)
223+
assertThat(parserOutput.iconType).isEqualTo(XML)
224+
assertThat(output).isEqualTo(expected)
225+
}
226+
227+
@ParameterizedTest
228+
@EnumSource(value = OutputFormat::class)
229+
fun `icon with compose colors and linear gradient`(outputFormat: OutputFormat) {
230+
val icon = getResourcePath("imagevector/xml/ic_compose_color_linear_gradient.xml")
231+
val parserOutput = SvgXmlParser.toIrImageVector(icon)
232+
val output = ImageVectorGenerator.convert(
233+
vector = parserOutput.irImageVector,
234+
iconName = parserOutput.iconName,
235+
config = createConfig(
236+
packName = "",
237+
outputFormat = outputFormat,
238+
useComposeColors = true,
239+
),
240+
).content
241+
242+
val expected = outputFormat.toResourceText(
243+
pathToBackingProperty = "imagevector/kt/backing/ComposeColor.linear.gradient.kt",
244+
pathToLazyProperty = "imagevector/kt/lazy/ComposeColor.linear.gradient.kt",
245+
)
246+
assertThat(parserOutput.iconType).isEqualTo(XML)
247+
assertThat(output).isEqualTo(expected)
248+
}
249+
250+
@ParameterizedTest
251+
@EnumSource(value = OutputFormat::class)
252+
fun `icon with compose colors and radial gradient`(outputFormat: OutputFormat) {
253+
val icon = getResourcePath("imagevector/xml/ic_compose_color_radial_gradient.xml")
254+
val parserOutput = SvgXmlParser.toIrImageVector(icon)
255+
val output = ImageVectorGenerator.convert(
256+
vector = parserOutput.irImageVector,
257+
iconName = parserOutput.iconName,
258+
config = createConfig(
259+
packName = "",
260+
outputFormat = outputFormat,
261+
useComposeColors = true,
262+
),
263+
).content
264+
265+
val expected = outputFormat.toResourceText(
266+
pathToBackingProperty = "imagevector/kt/backing/ComposeColor.radial.gradient.kt",
267+
pathToLazyProperty = "imagevector/kt/lazy/ComposeColor.radial.gradient.kt",
268+
)
269+
assertThat(parserOutput.iconType).isEqualTo(XML)
270+
assertThat(output).isEqualTo(expected)
271+
}
272+
189273
@ParameterizedTest
190274
@EnumSource(value = OutputFormat::class)
191275
fun `icon with transparent fill color`(outputFormat: OutputFormat) {

components/parser/common/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
alias(libs.plugins.valkyrie.kmp)
3+
alias(libs.plugins.kover)
34
}
45

56
kotlin {

components/parser/jvm/svg/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
alias(libs.plugins.kotlin.jvm)
3+
alias(libs.plugins.kover)
34
}
45

56
dependencies {

components/parser/jvm/xml/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
alias(libs.plugins.kotlin.jvm)
3+
alias(libs.plugins.kover)
34
}
45

56
dependencies {

components/parser/jvm/xml/src/main/kotlin/io/github/composegears/valkyrie/parser/jvm/xml/XmlToImageVectorParser.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,23 +157,43 @@ private fun parseGradient(parser: XmlPullParser): IrFill? {
157157
val startY = parser.valueAsFloat(START_Y) ?: 0f
158158
val endX = parser.valueAsFloat(END_X) ?: 0f
159159
val endY = parser.valueAsFloat(END_Y) ?: 0f
160+
val startColor = parser.valueAsIrColor(START_COLOR)
161+
val endColor = parser.valueAsIrColor(END_COLOR)
160162

161163
IrFill.LinearGradient(
162164
startY = startY,
163165
startX = startX,
164166
endY = endY,
165167
endX = endX,
168+
colorStops = if (startColor != null && endColor != null) {
169+
mutableListOf(
170+
IrFill.ColorStop(0f, startColor),
171+
IrFill.ColorStop(1f, endColor),
172+
)
173+
} else {
174+
mutableListOf()
175+
},
166176
)
167177
}
168178
RADIAL -> {
169179
val radius = parser.valueAsFloat(GRADIENT_RADIUS) ?: 0f
170180
val centerX = parser.valueAsFloat(CENTER_X) ?: 0f
171181
val centerY = parser.valueAsFloat(CENTER_Y) ?: 0f
182+
val startColor = parser.valueAsIrColor(START_COLOR)
183+
val endColor = parser.valueAsIrColor(END_COLOR)
172184

173185
IrFill.RadialGradient(
174186
radius = radius,
175187
centerX = centerX,
176188
centerY = centerY,
189+
colorStops = if (startColor != null && endColor != null) {
190+
mutableListOf(
191+
IrFill.ColorStop(0f, startColor),
192+
IrFill.ColorStop(1f, endColor),
193+
)
194+
} else {
195+
mutableListOf()
196+
},
177197
)
178198
}
179199
else -> null
@@ -235,6 +255,8 @@ private const val CENTER_Y = "android:centerY"
235255
// Item XML attribute names
236256
private const val OFFSET = "android:offset"
237257
private const val COLOR = "android:color"
258+
private const val START_COLOR = "android:startColor"
259+
private const val END_COLOR = "android:endColor"
238260

239261
// Vector XML attribute names
240262
private const val WIDTH = "android:width"

0 commit comments

Comments
 (0)