diff --git a/components/parser/kmp/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/xml/XmlToImageVectorParser.kt b/components/parser/kmp/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/xml/XmlToImageVectorParser.kt index a4fb9ec6e..807ba119c 100644 --- a/components/parser/kmp/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/xml/XmlToImageVectorParser.kt +++ b/components/parser/kmp/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/xml/XmlToImageVectorParser.kt @@ -37,9 +37,12 @@ object XmlToImageVectorParser { } private fun VectorDrawable.Path.toIrPath(): IrVectorNode.IrPath { + val gradientFill = aaptAttr?.gradient?.toIrFill() + val colorFill = fillColor?.toIrColor()?.let { IrFill.Color(it) } + return IrVectorNode.IrPath( name = name.orEmpty(), - fill = fillColor?.toIrColor()?.let { IrFill.Color(it) }, + fill = gradientFill ?: colorFill, fillAlpha = alpha, stroke = strokeColor?.toIrColor()?.let { IrStroke.Color(it) }, strokeAlpha = strokeAlpha?.toFloatOrNull() ?: 1f, @@ -84,4 +87,46 @@ object XmlToImageVectorParser { private fun String.asFillType(): IrPathFillType = IrPathFillType.entries.find { it.name.equals(this, ignoreCase = true) } ?: IrPathFillType.NonZero private fun String.toIrColor(): IrColor? = AndroidColorParser.parse(this) ?: IrColor(this).takeUnless { it.isTransparent() } + + private fun VectorDrawable.Gradient.toIrFill(): IrFill? { + return when (type.lowercase()) { + "linear" -> { + IrFill.LinearGradient( + startX = startX ?: 0f, + startY = startY ?: 0f, + endX = endX ?: 0f, + endY = endY ?: 0f, + colorStops = buildColorStops(), + ) + } + "radial" -> { + IrFill.RadialGradient( + radius = gradientRadius ?: 0f, + centerX = centerX ?: 0f, + centerY = centerY ?: 0f, + colorStops = buildColorStops(), + ) + } + else -> null + } + } + + private fun VectorDrawable.Gradient.buildColorStops(): MutableList { + return if (items.isNotEmpty()) { + items.mapNotNull { item -> + item.color.toIrColor()?.let { color -> + IrFill.ColorStop(item.offset, color) + } + } + } else { + buildList { + startColor?.toIrColor()?.let { color -> + add(IrFill.ColorStop(0f, color)) + } + endColor?.toIrColor()?.let { color -> + add(IrFill.ColorStop(1f, color)) + } + } + }.toMutableList() + } } diff --git a/components/parser/kmp/xml/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/xml/XmlToImageVectorParserTest.kt b/components/parser/kmp/xml/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/xml/XmlToImageVectorParserTest.kt index 42d312a1b..195d09cec 100644 --- a/components/parser/kmp/xml/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/xml/XmlToImageVectorParserTest.kt +++ b/components/parser/kmp/xml/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/xml/XmlToImageVectorParserTest.kt @@ -4,6 +4,9 @@ import io.github.composegears.valkyrie.sdk.ir.core.IrColor import io.github.composegears.valkyrie.sdk.ir.core.IrFill import io.github.composegears.valkyrie.sdk.ir.core.IrImageVector import io.github.composegears.valkyrie.sdk.ir.core.IrPathFillType +import io.github.composegears.valkyrie.sdk.ir.core.IrPathNode.Close +import io.github.composegears.valkyrie.sdk.ir.core.IrPathNode.LineTo +import io.github.composegears.valkyrie.sdk.ir.core.IrPathNode.MoveTo import io.github.composegears.valkyrie.sdk.ir.core.IrStroke import io.github.composegears.valkyrie.sdk.ir.core.IrStrokeLineCap import io.github.composegears.valkyrie.sdk.ir.core.IrStrokeLineJoin @@ -167,6 +170,292 @@ class XmlToImageVectorParserTest { } } + @Test + fun parse_path_with_linear_gradient() { + val vector = vectorWithGradient( + """ + + + + + + """.trimIndent(), + ) + + assertEquals( + expected = imageVector( + nodes = listOf( + IrVectorNode.IrPath( + pathFillType = IrPathFillType.NonZero, + fill = IrFill.LinearGradient( + startX = 0f, + startY = 0f, + endX = 10f, + endY = 10f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFFFF0000)), + IrFill.ColorStop(1f, IrColor(0xFF0000FF)), + ), + ), + fillAlpha = 1f, + paths = listOf(MoveTo(x = 0f, y = 0f), LineTo(x = 10f, y = 0f), LineTo(x = 10f, y = 10f), LineTo(x = 0f, y = 10f), Close), + ), + ), + ), + actual = XmlToImageVectorParser.parse(vector), + ) + } + + @Test + fun parse_path_with_radial_gradient() { + val vector = vectorWithGradient( + """ + + + + + + """.trimIndent(), + ) + + assertEquals( + expected = imageVector( + nodes = listOf( + IrVectorNode.IrPath( + pathFillType = IrPathFillType.NonZero, + fill = IrFill.RadialGradient( + centerX = 5f, + centerY = 5f, + radius = 7.5f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFF00FF00)), + IrFill.ColorStop(1f, IrColor(0xFFFFFF00)), + ), + ), + fillAlpha = 1f, + paths = listOf( + MoveTo(x = 0f, y = 0f), + LineTo(x = 10f, y = 0f), + LineTo(x = 10f, y = 10f), + LineTo(x = 0f, y = 10f), + Close, + ), + ), + ), + ), + actual = XmlToImageVectorParser.parse(vector), + ) + } + + @Test + fun parse_path_with_linear_gradient_and_color_stops() { + val vector = vectorWithGradient( + """ + + + + + + + + + + """.trimIndent(), + ) + + assertEquals( + expected = imageVector( + nodes = listOf( + IrVectorNode.IrPath( + pathFillType = IrPathFillType.NonZero, + fill = IrFill.LinearGradient( + startX = 0f, + startY = 0f, + endX = 10f, + endY = 0f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFFFF0000)), + IrFill.ColorStop(0.5f, IrColor(0xFF00FF00)), + IrFill.ColorStop(1f, IrColor(0xFF0000FF)), + ), + ), + fillAlpha = 1f, + paths = listOf(MoveTo(x = 0f, y = 0f), LineTo(x = 10f, y = 0f), LineTo(x = 10f, y = 10f), LineTo(x = 0f, y = 10f), Close), + ), + ), + ), + actual = XmlToImageVectorParser.parse(vector), + ) + } + + @Test + fun parse_path_with_radial_gradient_and_color_stops() { + val vector = vectorWithGradient( + """ + + + + + + + + + + """.trimIndent(), + ) + + assertEquals( + expected = imageVector( + nodes = listOf( + IrVectorNode.IrPath( + pathFillType = IrPathFillType.NonZero, + fill = IrFill.RadialGradient( + centerX = 5f, + centerY = 5f, + radius = 10f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFFFFFFFF)), + IrFill.ColorStop(0.7f, IrColor(0xFF888888)), + IrFill.ColorStop(1f, IrColor(0xFF000000)), + ), + ), + fillAlpha = 1f, + paths = listOf(MoveTo(x = 0f, y = 0f), LineTo(x = 10f, y = 0f), LineTo(x = 10f, y = 10f), LineTo(x = 0f, y = 10f), Close), + ), + ), + ), + actual = XmlToImageVectorParser.parse(vector), + ) + } + + @Test + fun parse_multiple_paths_with_gradients() { + val vector = vectorWithGradient( + """ + + + + + + + + + + + """.trimIndent(), + ) + val result = XmlToImageVectorParser.parse(vector) + + assertEquals(2, result.nodes.size) + val firstPath = result.nodes[0] as IrVectorNode.IrPath + val secondPath = result.nodes[1] as IrVectorNode.IrPath + + assertEquals( + expected = IrFill.LinearGradient( + startX = 0f, + startY = 0f, + endX = 5f, + endY = 0f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFFFF0000)), + IrFill.ColorStop(1f, IrColor(0xFF00FF00)), + ), + ), + actual = firstPath.fill, + ) + + assertEquals( + expected = IrFill.RadialGradient( + centerX = 8f, + centerY = 2.5f, + radius = 2.5f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFF0000FF)), + IrFill.ColorStop(1f, IrColor(0xFFFFFF00)), + ), + ), + actual = secondPath.fill, + ) + } + + @Test + fun parse_path_with_gradient_in_group() { + val vector = vectorWithGradient( + """ + + + + + + + + """.trimIndent(), + ) + val result = XmlToImageVectorParser.parse(vector) + + assertEquals(1, result.nodes.size) + val group = result.nodes[0] as IrVectorNode.IrGroup + assertEquals("gradientGroup", group.name) + assertEquals(1, group.nodes.size) + + val path = group.nodes[0] as IrVectorNode.IrPath + assertEquals( + expected = IrFill.LinearGradient( + startX = 0f, + startY = 0f, + endX = 10f, + endY = 10f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFFFFFFFF)), + IrFill.ColorStop(1f, IrColor(0xFF000000)), + ), + ), + actual = path.fill, + ) + } + private fun vector( content: String, width: String = "24dp", @@ -185,6 +474,25 @@ class XmlToImageVectorParserTest { appendLine("") } + private fun vectorWithGradient( + content: String, + width: String = "24dp", + height: String = "24dp", + ): String = buildString { + appendLine( + """ + + """.trimIndent(), + ) + appendLine(content) + appendLine("") + } + private fun imageVector(nodes: List = emptyList()): IrImageVector = IrImageVector( defaultWidth = 24f, defaultHeight = 24f, diff --git a/components/parser/unified/src/jvmTest/kotlin/io/github/composegears/valkyrie/parser/unified/XmlToImageVectorTest.kt b/components/parser/unified/src/jvmTest/kotlin/io/github/composegears/valkyrie/parser/unified/XmlToImageVectorTest.kt index 1bd16646e..e05514e3a 100644 --- a/components/parser/unified/src/jvmTest/kotlin/io/github/composegears/valkyrie/parser/unified/XmlToImageVectorTest.kt +++ b/components/parser/unified/src/jvmTest/kotlin/io/github/composegears/valkyrie/parser/unified/XmlToImageVectorTest.kt @@ -10,7 +10,6 @@ import io.github.composegears.valkyrie.parser.unified.model.IconType import io.github.composegears.valkyrie.resource.loader.ResourceLoader.getResourcePath import kotlin.test.assertEquals import kotlinx.io.files.Path -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test class XmlToImageVectorTest { @@ -66,16 +65,12 @@ class XmlToImageVectorTest { } @Test - @Disabled fun `icon with compose colors and linear gradient`() { - // TODO: update kmp linear gradient parsing unifiedXmlParserTest(iconPath = getResourcePath("imagevector/xml/ic_compose_color_linear_gradient.xml").toIOPath()) } @Test - @Disabled fun `icon with compose colors and radial gradient`() { - // TODO: update kmp radial gradient parsing unifiedXmlParserTest(iconPath = getResourcePath("imagevector/xml/ic_compose_color_radial_gradient.xml").toIOPath()) } diff --git a/sdk/core/xml/api/xml.api b/sdk/core/xml/api/xml.api index 6d4699008..c91e03753 100644 --- a/sdk/core/xml/api/xml.api +++ b/sdk/core/xml/api/xml.api @@ -1,6 +1,8 @@ public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable { public static final field CLIP_PATH Ljava/lang/String; public static final field Companion Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Companion; + public static final field GRADIENT Ljava/lang/String; + public static final field GRADIENT_ITEM Ljava/lang/String; public static final field GROUP Ljava/lang/String; public static final field PATH Ljava/lang/String; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FFLjava/lang/String;ZLjava/util/List;)V @@ -39,6 +41,36 @@ public final synthetic class io/github/composegears/valkyrie/sdk/core/xml/Vector public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; } +public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr { + public static final field Companion Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr$Companion; + public fun (Ljava/lang/String;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient;)V + public synthetic fun (Ljava/lang/String;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient; + public final fun copy (Ljava/lang/String;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr; + public static synthetic fun copy$default (Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr;Ljava/lang/String;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient;ILjava/lang/Object;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr; + public fun equals (Ljava/lang/Object;)Z + public final fun getGradient ()Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient; + public final fun getName ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final synthetic class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr$$serializer; + public final fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + public abstract interface class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Child { } @@ -76,6 +108,83 @@ public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$C public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient { + public static final field Companion Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient$Companion; + public fun (Ljava/lang/String;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component10 ()Ljava/lang/String; + public final fun component11 ()Ljava/util/List; + public final fun component2 ()Ljava/lang/Float; + public final fun component3 ()Ljava/lang/Float; + public final fun component4 ()Ljava/lang/Float; + public final fun component5 ()Ljava/lang/Float; + public final fun component6 ()Ljava/lang/Float; + public final fun component7 ()Ljava/lang/Float; + public final fun component8 ()Ljava/lang/Float; + public final fun component9 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient; + public static synthetic fun copy$default (Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient;Ljava/lang/String;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILjava/lang/Object;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient; + public fun equals (Ljava/lang/Object;)Z + public final fun getCenterX ()Ljava/lang/Float; + public final fun getCenterY ()Ljava/lang/Float; + public final fun getEndColor ()Ljava/lang/String; + public final fun getEndX ()Ljava/lang/Float; + public final fun getEndY ()Ljava/lang/Float; + public final fun getGradientRadius ()Ljava/lang/Float; + public final fun getItems ()Ljava/util/List; + public final fun getStartColor ()Ljava/lang/String; + public final fun getStartX ()Ljava/lang/Float; + public final fun getStartY ()Ljava/lang/Float; + public final fun getType ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final synthetic class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient$$serializer; + public final fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Gradient$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem { + public static final field Companion Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem$Companion; + public fun (Ljava/lang/String;F)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()F + public final fun copy (Ljava/lang/String;F)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem; + public static synthetic fun copy$default (Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem;Ljava/lang/String;FILjava/lang/Object;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem; + public fun equals (Ljava/lang/Object;)Z + public final fun getColor ()Ljava/lang/String; + public final fun getOffset ()F + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final synthetic class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem$$serializer; + public final fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$GradientItem$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Group : io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Child { public static final field Companion Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Group$Companion; public fun (Ljava/lang/String;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/util/List;)V @@ -122,11 +231,12 @@ public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$G public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Path : io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Child { public static final field Companion Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Path$Companion; - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; public final fun component10 ()Ljava/lang/String; public final fun component11 ()Ljava/lang/String; + public final fun component12 ()Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr; public final fun component2 ()Ljava/lang/String; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; @@ -135,9 +245,10 @@ public final class io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$P public final fun component7 ()Ljava/lang/String; public final fun component8 ()Ljava/lang/String; public final fun component9 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Path; - public static synthetic fun copy$default (Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Path;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Path; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Path; + public static synthetic fun copy$default (Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Path;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr;ILjava/lang/Object;)Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$Path; public fun equals (Ljava/lang/Object;)Z + public final fun getAaptAttr ()Lio/github/composegears/valkyrie/sdk/core/xml/VectorDrawable$AaptAttr; public final fun getAlpha ()F public final fun getFillColor ()Ljava/lang/String; public final fun getFillType ()Ljava/lang/String; diff --git a/sdk/core/xml/api/xml.klib.api b/sdk/core/xml/api/xml.klib.api index 9646f3f65..a4bb0eba1 100644 --- a/sdk/core/xml/api/xml.klib.api +++ b/sdk/core/xml/api/xml.klib.api @@ -41,6 +41,35 @@ final class io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable { // io. sealed interface Child // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Child|null[0] + final class AaptAttr { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr|null[0] + constructor (kotlin/String, io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient? = ...) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.|(kotlin.String;io.github.composegears.valkyrie.sdk.core.xml.VectorDrawable.Gradient?){}[0] + + final val gradient // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.gradient|{}gradient[0] + final fun (): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.gradient.|(){}[0] + final val name // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.name|{}name[0] + final fun (): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.name.|(){}[0] + + final fun component1(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.component1|component1(){}[0] + final fun component2(): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.component2|component2(){}[0] + final fun copy(kotlin/String = ..., io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient? = ...): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.copy|copy(kotlin.String;io.github.composegears.valkyrie.sdk.core.xml.VectorDrawable.Gradient?){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.toString|toString(){}[0] + + final object $serializer : kotlinx.serialization.internal/GeneratedSerializer { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.$serializer|null[0] + final val descriptor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.$serializer.descriptor|{}descriptor[0] + final fun (): kotlinx.serialization.descriptors/SerialDescriptor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.$serializer.descriptor.|(){}[0] + + final fun childSerializers(): kotlin/Array> // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.$serializer.childSerializers|childSerializers(){}[0] + final fun deserialize(kotlinx.serialization.encoding/Decoder): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.$serializer.deserialize|deserialize(kotlinx.serialization.encoding.Decoder){}[0] + final fun serialize(kotlinx.serialization.encoding/Encoder, io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.$serializer.serialize|serialize(kotlinx.serialization.encoding.Encoder;io.github.composegears.valkyrie.sdk.core.xml.VectorDrawable.AaptAttr){}[0] + } + + final object Companion { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.Companion|null[0] + final fun serializer(): kotlinx.serialization/KSerializer // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr.Companion.serializer|serializer(){}[0] + } + } + final class ClipPath : io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Child { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.ClipPath|null[0] constructor (kotlin/String? = ..., kotlin/String) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.ClipPath.|(kotlin.String?;kotlin.String){}[0] @@ -70,6 +99,93 @@ final class io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable { // io. } } + final class Gradient { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient|null[0] + constructor (kotlin/String, kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin.collections/List = ...) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.|(kotlin.String;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.String?;kotlin.String?;kotlin.collections.List){}[0] + + final val centerX // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.centerX|{}centerX[0] + final fun (): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.centerX.|(){}[0] + final val centerY // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.centerY|{}centerY[0] + final fun (): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.centerY.|(){}[0] + final val endColor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.endColor|{}endColor[0] + final fun (): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.endColor.|(){}[0] + final val endX // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.endX|{}endX[0] + final fun (): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.endX.|(){}[0] + final val endY // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.endY|{}endY[0] + final fun (): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.endY.|(){}[0] + final val gradientRadius // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.gradientRadius|{}gradientRadius[0] + final fun (): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.gradientRadius.|(){}[0] + final val items // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.items|{}items[0] + final fun (): kotlin.collections/List // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.items.|(){}[0] + final val startColor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.startColor|{}startColor[0] + final fun (): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.startColor.|(){}[0] + final val startX // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.startX|{}startX[0] + final fun (): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.startX.|(){}[0] + final val startY // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.startY|{}startY[0] + final fun (): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.startY.|(){}[0] + final val type // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.type|{}type[0] + final fun (): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.type.|(){}[0] + + final fun component1(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component1|component1(){}[0] + final fun component10(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component10|component10(){}[0] + final fun component11(): kotlin.collections/List // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component11|component11(){}[0] + final fun component2(): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component2|component2(){}[0] + final fun component3(): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component3|component3(){}[0] + final fun component4(): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component4|component4(){}[0] + final fun component5(): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component5|component5(){}[0] + final fun component6(): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component6|component6(){}[0] + final fun component7(): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component7|component7(){}[0] + final fun component8(): kotlin/Float? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component8|component8(){}[0] + final fun component9(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.component9|component9(){}[0] + final fun copy(kotlin/String = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin.collections/List = ...): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.copy|copy(kotlin.String;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.String?;kotlin.String?;kotlin.collections.List){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.toString|toString(){}[0] + + final object $serializer : kotlinx.serialization.internal/GeneratedSerializer { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.$serializer|null[0] + final val descriptor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.$serializer.descriptor|{}descriptor[0] + final fun (): kotlinx.serialization.descriptors/SerialDescriptor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.$serializer.descriptor.|(){}[0] + + final fun childSerializers(): kotlin/Array> // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.$serializer.childSerializers|childSerializers(){}[0] + final fun deserialize(kotlinx.serialization.encoding/Decoder): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.$serializer.deserialize|deserialize(kotlinx.serialization.encoding.Decoder){}[0] + final fun serialize(kotlinx.serialization.encoding/Encoder, io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.$serializer.serialize|serialize(kotlinx.serialization.encoding.Encoder;io.github.composegears.valkyrie.sdk.core.xml.VectorDrawable.Gradient){}[0] + } + + final object Companion { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.Companion|null[0] + final val $childSerializers // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.Companion.$childSerializers|{}$childSerializers[0] + + final fun serializer(): kotlinx.serialization/KSerializer // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Gradient.Companion.serializer|serializer(){}[0] + } + } + + final class GradientItem { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem|null[0] + constructor (kotlin/String, kotlin/Float) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.|(kotlin.String;kotlin.Float){}[0] + + final val color // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.color|{}color[0] + final fun (): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.color.|(){}[0] + final val offset // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.offset|{}offset[0] + final fun (): kotlin/Float // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.offset.|(){}[0] + + final fun component1(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.component1|component1(){}[0] + final fun component2(): kotlin/Float // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.component2|component2(){}[0] + final fun copy(kotlin/String = ..., kotlin/Float = ...): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.copy|copy(kotlin.String;kotlin.Float){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.toString|toString(){}[0] + + final object $serializer : kotlinx.serialization.internal/GeneratedSerializer { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.$serializer|null[0] + final val descriptor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.$serializer.descriptor|{}descriptor[0] + final fun (): kotlinx.serialization.descriptors/SerialDescriptor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.$serializer.descriptor.|(){}[0] + + final fun childSerializers(): kotlin/Array> // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.$serializer.childSerializers|childSerializers(){}[0] + final fun deserialize(kotlinx.serialization.encoding/Decoder): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.$serializer.deserialize|deserialize(kotlinx.serialization.encoding.Decoder){}[0] + final fun serialize(kotlinx.serialization.encoding/Encoder, io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.$serializer.serialize|serialize(kotlinx.serialization.encoding.Encoder;io.github.composegears.valkyrie.sdk.core.xml.VectorDrawable.GradientItem){}[0] + } + + final object Companion { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.Companion|null[0] + final fun serializer(): kotlinx.serialization/KSerializer // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.GradientItem.Companion.serializer|serializer(){}[0] + } + } + final class Group : io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Child { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Group|null[0] constructor (kotlin/String? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin/Float? = ..., kotlin.collections/List) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Group.|(kotlin.String?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.Float?;kotlin.collections.List){}[0] @@ -123,8 +239,10 @@ final class io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable { // io. } final class Path : io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Child { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path|null[0] - constructor (kotlin/String? = ..., kotlin/String = ..., kotlin/String? = ..., kotlin/String, kotlin/Float = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ...) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.|(kotlin.String?;kotlin.String;kotlin.String?;kotlin.String;kotlin.Float;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?){}[0] + constructor (kotlin/String? = ..., kotlin/String = ..., kotlin/String? = ..., kotlin/String, kotlin/Float = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr? = ...) // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.|(kotlin.String?;kotlin.String;kotlin.String?;kotlin.String;kotlin.Float;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;io.github.composegears.valkyrie.sdk.core.xml.VectorDrawable.AaptAttr?){}[0] + final val aaptAttr // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.aaptAttr|{}aaptAttr[0] + final fun (): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.aaptAttr.|(){}[0] final val alpha // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.alpha|{}alpha[0] final fun (): kotlin/Float // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.alpha.|(){}[0] final val fillColor // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.fillColor|{}fillColor[0] @@ -151,6 +269,7 @@ final class io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable { // io. final fun component1(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component1|component1(){}[0] final fun component10(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component10|component10(){}[0] final fun component11(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component11|component11(){}[0] + final fun component12(): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component12|component12(){}[0] final fun component2(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component2|component2(){}[0] final fun component3(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component3|component3(){}[0] final fun component4(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component4|component4(){}[0] @@ -159,7 +278,7 @@ final class io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable { // io. final fun component7(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component7|component7(){}[0] final fun component8(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component8|component8(){}[0] final fun component9(): kotlin/String? // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.component9|component9(){}[0] - final fun copy(kotlin/String? = ..., kotlin/String = ..., kotlin/String? = ..., kotlin/String = ..., kotlin/Float = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ...): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.copy|copy(kotlin.String?;kotlin.String;kotlin.String?;kotlin.String;kotlin.Float;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?){}[0] + final fun copy(kotlin/String? = ..., kotlin/String = ..., kotlin/String? = ..., kotlin/String = ..., kotlin/Float = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., kotlin/String? = ..., io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.AaptAttr? = ...): io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.copy|copy(kotlin.String?;kotlin.String;kotlin.String?;kotlin.String;kotlin.Float;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.String?;io.github.composegears.valkyrie.sdk.core.xml.VectorDrawable.AaptAttr?){}[0] final fun equals(kotlin/Any?): kotlin/Boolean // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.equals|equals(kotlin.Any?){}[0] final fun hashCode(): kotlin/Int // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.hashCode|hashCode(){}[0] final fun toString(): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Path.toString|toString(){}[0] @@ -190,6 +309,10 @@ final class io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable { // io. final object Companion { // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion|null[0] final const val CLIP_PATH // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.CLIP_PATH|{}CLIP_PATH[0] final fun (): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.CLIP_PATH.|(){}[0] + final const val GRADIENT // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.GRADIENT|{}GRADIENT[0] + final fun (): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.GRADIENT.|(){}[0] + final const val GRADIENT_ITEM // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.GRADIENT_ITEM|{}GRADIENT_ITEM[0] + final fun (): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.GRADIENT_ITEM.|(){}[0] final const val GROUP // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.GROUP|{}GROUP[0] final fun (): kotlin/String // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.GROUP.|(){}[0] final const val PATH // io.github.composegears.valkyrie.sdk.core.xml/VectorDrawable.Companion.PATH|{}PATH[0] diff --git a/sdk/core/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable.kt b/sdk/core/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable.kt index 00396ec37..4bbb168dc 100644 --- a/sdk/core/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable.kt +++ b/sdk/core/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/core/xml/VectorDrawable.kt @@ -8,6 +8,8 @@ import nl.adaptivity.xmlutil.serialization.XmlSerialName private const val ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android" private const val ANDROID_PREFIX = "android" +private const val AAPT_NAMESPACE = "http://schemas.android.com/aapt" +private const val AAPT_PREFIX = "aapt" @XmlSerialName(value = "vector", prefix = ANDROID_PREFIX) @Serializable @@ -27,10 +29,45 @@ data class VectorDrawable( const val GROUP = "group" const val PATH = "path" const val CLIP_PATH = "clip-path" + const val GRADIENT = "gradient" + const val GRADIENT_ITEM = "item" } sealed interface Child + @Serializable + @SerialName(GRADIENT) + @XmlSerialName(value = GRADIENT) + data class Gradient( + @XmlSerialName("type", ANDROID_NAMESPACE, ANDROID_PREFIX) val type: String, + @XmlSerialName("startX", ANDROID_NAMESPACE, ANDROID_PREFIX) val startX: Float? = null, + @XmlSerialName("startY", ANDROID_NAMESPACE, ANDROID_PREFIX) val startY: Float? = null, + @XmlSerialName("endX", ANDROID_NAMESPACE, ANDROID_PREFIX) val endX: Float? = null, + @XmlSerialName("endY", ANDROID_NAMESPACE, ANDROID_PREFIX) val endY: Float? = null, + @XmlSerialName("centerX", ANDROID_NAMESPACE, ANDROID_PREFIX) val centerX: Float? = null, + @XmlSerialName("centerY", ANDROID_NAMESPACE, ANDROID_PREFIX) val centerY: Float? = null, + @XmlSerialName("gradientRadius", ANDROID_NAMESPACE, ANDROID_PREFIX) val gradientRadius: Float? = null, + @XmlSerialName("startColor", ANDROID_NAMESPACE, ANDROID_PREFIX) val startColor: String? = null, + @XmlSerialName("endColor", ANDROID_NAMESPACE, ANDROID_PREFIX) val endColor: String? = null, + val items: List = emptyList(), + ) + + @Serializable + @SerialName(GRADIENT_ITEM) + @XmlSerialName(value = GRADIENT_ITEM) + data class GradientItem( + @XmlSerialName("color", ANDROID_NAMESPACE, ANDROID_PREFIX) val color: String, + @XmlSerialName("offset", ANDROID_NAMESPACE, ANDROID_PREFIX) val offset: Float, + ) + + @Serializable + @SerialName("attr") + @XmlSerialName(value = "attr", namespace = AAPT_NAMESPACE, prefix = AAPT_PREFIX) + data class AaptAttr( + @XmlSerialName("name") val name: String, + val gradient: Gradient? = null, + ) + @Serializable @SerialName(GROUP) @XmlSerialName(value = GROUP, prefix = ANDROID_PREFIX) @@ -63,6 +100,7 @@ data class VectorDrawable( @XmlSerialName("strokeColor", ANDROID_NAMESPACE, ANDROID_PREFIX) val strokeColor: String? = null, @XmlSerialName("strokeAlpha", ANDROID_NAMESPACE, ANDROID_PREFIX) val strokeAlpha: String? = null, @XmlSerialName("strokeMiterLimit", ANDROID_NAMESPACE, ANDROID_PREFIX) val strokeMiterLimit: String? = null, + val aaptAttr: AaptAttr? = null, ) : Child @Serializable diff --git a/sdk/generator/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/IrToXmlGenerator.kt b/sdk/generator/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/IrToXmlGenerator.kt index d49bcadde..be928a70e 100644 --- a/sdk/generator/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/IrToXmlGenerator.kt +++ b/sdk/generator/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/IrToXmlGenerator.kt @@ -86,6 +86,81 @@ object IrToXmlGenerator { strokeColor = strokeColorStr, strokeAlpha = strokeAlpha.takeIf { it != 1f }?.let { formatFloatValue(it) }, strokeMiterLimit = strokeLineMiter.takeIf { it != 4f }?.let { formatFloatValue(it) }, + aaptAttr = fill?.toAaptAttr(), + ) + } + + private fun IrFill.toAaptAttr(): VectorDrawable.AaptAttr? { + return when (this) { + is IrFill.LinearGradient -> VectorDrawable.AaptAttr( + name = "android:fillColor", + gradient = toVectorDrawableGradient(), + ) + is IrFill.RadialGradient -> VectorDrawable.AaptAttr( + name = "android:fillColor", + gradient = toVectorDrawableGradient(), + ) + else -> null + } + } + + private fun IrFill.LinearGradient.toVectorDrawableGradient(): VectorDrawable.Gradient { + // Use startColor/endColor for simple 2-color gradients (0.0 to 1.0) + val useSimpleFormat = colorStops.size == 2 && + colorStops.first().offset == 0f && + colorStops.last().offset == 1f + + return VectorDrawable.Gradient( + type = "linear", + startX = startX, + startY = startY, + endX = endX, + endY = endY, + centerX = null, + centerY = null, + gradientRadius = null, + startColor = colorStops.first().irColor.toHexColor().takeIf { useSimpleFormat }, + endColor = colorStops.last().irColor.toHexColor().takeIf { useSimpleFormat }, + items = if (useSimpleFormat) { + emptyList() + } else { + colorStops.map { colorStop -> + VectorDrawable.GradientItem( + color = colorStop.irColor.toHexColor(), + offset = colorStop.offset, + ) + } + }, + ) + } + + private fun IrFill.RadialGradient.toVectorDrawableGradient(): VectorDrawable.Gradient { + // Use startColor/endColor for simple 2-color gradients (0.0 to 1.0) + val useSimpleFormat = colorStops.size == 2 && + colorStops.first().offset == 0f && + colorStops.last().offset == 1f + + return VectorDrawable.Gradient( + type = "radial", + startX = null, + startY = null, + endX = null, + endY = null, + centerX = centerX, + centerY = centerY, + gradientRadius = radius, + startColor = colorStops.first().irColor.toHexColor().takeIf { useSimpleFormat }, + endColor = colorStops.last().irColor.toHexColor().takeIf { useSimpleFormat }, + items = if (useSimpleFormat) { + emptyList() + } else { + colorStops.map { colorStop -> + VectorDrawable.GradientItem( + color = colorStop.irColor.toHexColor(), + offset = colorStop.offset, + ) + } + }, ) } diff --git a/sdk/generator/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/XmlSerializer.kt b/sdk/generator/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/XmlSerializer.kt index 852e02829..9bc12fe57 100644 --- a/sdk/generator/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/XmlSerializer.kt +++ b/sdk/generator/xml/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/XmlSerializer.kt @@ -31,7 +31,26 @@ internal object XmlSerializer { fun serialize(vector: VectorDrawable): String { val rawXml = xmlConfig.encodeToString(vector) - return formatXmlAttributes(rawXml) + val formattedXml = formatXmlAttributes(rawXml) + return hoistAaptNamespace(formattedXml) + } + + /** + * Moves xmlns:aapt namespace declaration from individual aapt:attr elements to the root vector element. + */ + private fun hoistAaptNamespace(xml: String): String { + if (!xml.contains("]*xmlns:android="http://schemas\.android\.com/apk/res/android")"""), + """$1 xmlns:aapt="http://schemas.android.com/aapt"""", + ) + + return result } /** diff --git a/sdk/generator/xml/src/commonTest/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/IrToXmlGeneratorTest.kt b/sdk/generator/xml/src/commonTest/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/IrToXmlGeneratorTest.kt index 88e5fe016..7338cae17 100644 --- a/sdk/generator/xml/src/commonTest/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/IrToXmlGeneratorTest.kt +++ b/sdk/generator/xml/src/commonTest/kotlin/io/github/composegears/valkyrie/sdk/generator/xml/IrToXmlGeneratorTest.kt @@ -409,20 +409,26 @@ class IrToXmlGeneratorTest { } @Test - fun `round trip test for ic_brush xml - GRADIENTS NOT FULLY SUPPORTED`() { + fun `round trip test for ic_brush xml`() { val generatedXml = roundTripGenerateXml("imagevector/xml/ic_brush.xml") validateVectorAttributes(xml = generatedXml, size = 24, viewportSize = 18f) - // TODO: Original has 3 paths with complex linear and radial gradients - // Note: The gradient information will be lost in current parsing/generation - // This needs to be addressed when full gradient support is implemented val pathCount = generatedXml.split(" 0, "Should have gradient definitions") } @Test @@ -566,6 +591,123 @@ class IrToXmlGeneratorTest { } } + @Test + fun `parse ImageVector with linear gradient`() { + val imageVector = imageVector( + nodes = listOf( + IrVectorNode.IrPath( + pathFillType = IrPathFillType.NonZero, + fill = IrFill.LinearGradient( + startX = 0f, + startY = 0f, + endX = 10f, + endY = 10f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFFFF0000)), + IrFill.ColorStop(1f, IrColor(0xFF0000FF)), + ), + ), + fillAlpha = 1f, + paths = emptyList(), + ), + ), + ) + + val result = IrToXmlGenerator.generate(imageVector) + + with(result) { + assertTrue(contains("xmlns:aapt=")) + assertTrue(contains("")) + } + } + + @Test + fun `parse ImageVector with radial gradient`() { + val imageVector = imageVector( + nodes = listOf( + IrVectorNode.IrPath( + pathFillType = IrPathFillType.NonZero, + fill = IrFill.RadialGradient( + centerX = 5f, + centerY = 5f, + radius = 7.5f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFF00FF00)), + IrFill.ColorStop(1f, IrColor(0xFFFFFF00)), + ), + ), + fillAlpha = 1f, + paths = emptyList(), + ), + ), + ) + + val result = IrToXmlGenerator.generate(imageVector) + + with(result) { + assertTrue(contains("xmlns:aapt=")) + assertTrue(contains("")) + } + } + + @Test + fun `parse ImageVector with linear gradient with multiple color stops`() { + val imageVector = imageVector( + nodes = listOf( + IrVectorNode.IrPath( + pathFillType = IrPathFillType.NonZero, + fill = IrFill.LinearGradient( + startX = 0f, + startY = 0f, + endX = 10f, + endY = 0f, + colorStops = mutableListOf( + IrFill.ColorStop(0f, IrColor(0xFFFF0000)), + IrFill.ColorStop(0.5f, IrColor(0xFF00FF00)), + IrFill.ColorStop(1f, IrColor(0xFF0000FF)), + ), + ), + fillAlpha = 1f, + paths = emptyList(), + ), + ), + ) + + val result = IrToXmlGenerator.generate(imageVector) + + with(result) { + assertTrue(contains("android:type=\"linear\"")) + assertTrue(contains("android:color=\"#FFFF0000\"")) + assertTrue(contains("android:offset=\"0")) + assertTrue(contains("android:color=\"#FF00FF00\"")) + assertTrue(contains("android:offset=\"0.5\"")) + assertTrue(contains("android:color=\"#FF0000FF\"")) + assertTrue(contains("android:offset=\"1")) + + val itemCount = result.split("