From 0eb947f646c1c8ba818775725934761438b252e3 Mon Sep 17 00:00:00 2001 From: Infi Date: Tue, 5 Nov 2024 22:50:50 +0100 Subject: [PATCH] feat: rudimentary support for radial gradient brush Signed-off-by: Infi --- .../chat/revolt/api/internals/BrushCompat.kt | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/app/src/main/java/chat/revolt/api/internals/BrushCompat.kt b/app/src/main/java/chat/revolt/api/internals/BrushCompat.kt index 9fe79a69..37999980 100644 --- a/app/src/main/java/chat/revolt/api/internals/BrushCompat.kt +++ b/app/src/main/java/chat/revolt/api/internals/BrushCompat.kt @@ -85,6 +85,61 @@ object BrushCompat { ) } + @Composable + private fun parseRadialGradient(gradient: String): Brush { + val stops = mutableListOf>() + + val parts = mutableListOf() + var startIndex = 0 + var openParenthesesCount = 0 + + // Split the gradient string into individual components + for (i in gradient.indices) { + when (gradient[i]) { + '(' -> openParenthesesCount++ + ')' -> openParenthesesCount-- + ',' -> { + if (openParenthesesCount == 0) { + val part = gradient.substring(startIndex, i).trim() + parts.add(part) + startIndex = i + 1 + } + } + } + } + val lastPart = gradient.substring(startIndex).trim() + if (lastPart.isNotEmpty()) { + parts.add(lastPart) + } + + // Parse color stops + parts.drop(1).forEachIndexed { index, part -> + val splitPart = part.split(" ") + val colorPart = splitPart[0] + val color = when { + colorPart.startsWith("var(") -> { + parseVarToColour( + colorPart.substringAfter("var(").substringBeforeLast(")") + ) + } + + else -> parseFunctionColour(colorPart) ?: parseColourName(colorPart) + } + + val stop = if (splitPart.size == 2) { + splitPart[1].removeSuffix("%").toFloat() / 100f + } else { + index.toFloat() / (parts.size - 2) + } + + stops.add(stop to color) + } + + return Brush.radialGradient( + colorStops = stops.toTypedArray() + ) + } + fun parseFunctionColour(colourString: String): Color? { val cleanedString = colourString.trim() @@ -188,6 +243,16 @@ object BrushCompat { ) } + colour.startsWith("radial-gradient(") || colour.startsWith("repeating-radial-gradient(") -> { + return parseRadialGradient( + colour + .substringAfter("repeating-") + .substringAfter("radial-gradient(") + .substringBeforeLast(")") + ) + } + + else -> { return Brush.solidColor(parseColourName(colour)) }