-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[resources] Support SVG drawables for non android platforms (#4605)
- Loading branch information
Showing
11 changed files
with
307 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
...d/src/androidMain/kotlin/org/jetbrains/compose/resources/demo/shared/ImagesRes.android.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.jetbrains.compose.resources.demo.shared | ||
|
||
import androidx.compose.runtime.Composable | ||
|
||
@Composable | ||
actual fun SvgShowcase() { | ||
//Android platform doesn't support SVG resources | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
.../resources/demo/shared/src/nonAndroidMain/composeResources/drawable/sailing.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions
39
...nonAndroidMain/kotlin/org/jetbrains/compose/resources/demo/shared/ImagesRes.nonAndroid.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package org.jetbrains.compose.resources.demo.shared | ||
|
||
import androidx.compose.foundation.Image | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.layout.size | ||
import androidx.compose.material3.OutlinedCard | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.unit.dp | ||
import components.resources.demo.shared.generated.resources.Res | ||
import components.resources.demo.shared.generated.resources.sailing | ||
import org.jetbrains.compose.resources.painterResource | ||
|
||
@Composable | ||
actual fun SvgShowcase() { | ||
OutlinedCard(modifier = Modifier.padding(8.dp)) { | ||
Column( | ||
modifier = Modifier.padding(16.dp).fillMaxWidth(), | ||
horizontalAlignment = Alignment.CenterHorizontally | ||
) { | ||
Image( | ||
modifier = Modifier.size(100.dp), | ||
painter = painterResource(Res.drawable.sailing), | ||
contentDescription = null | ||
) | ||
Text( | ||
""" | ||
Image( | ||
painter = painterResource(Res.drawable.sailing) | ||
) | ||
""".trimIndent() | ||
) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
...nents/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/DrawCache.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package org.jetbrains.compose.resources | ||
|
||
import androidx.compose.ui.graphics.BlendMode | ||
import androidx.compose.ui.graphics.Canvas | ||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.graphics.ColorFilter | ||
import androidx.compose.ui.graphics.ImageBitmap | ||
import androidx.compose.ui.graphics.ImageBitmapConfig | ||
import androidx.compose.ui.graphics.drawscope.CanvasDrawScope | ||
import androidx.compose.ui.graphics.drawscope.DrawScope | ||
import androidx.compose.ui.unit.Density | ||
import androidx.compose.ui.unit.IntSize | ||
import androidx.compose.ui.unit.LayoutDirection | ||
import androidx.compose.ui.unit.toSize | ||
|
||
/** | ||
* Creates a drawing environment that directs its drawing commands to an [ImageBitmap] | ||
* which can be drawn directly in another [DrawScope] instance. This is useful to cache | ||
* complicated drawing commands across frames especially if the content has not changed. | ||
* Additionally some drawing operations such as rendering paths are done purely in | ||
* software so it is beneficial to cache the result and render the contents | ||
* directly through a texture as done by [DrawScope.drawImage] | ||
*/ | ||
internal class DrawCache { | ||
|
||
@PublishedApi internal var mCachedImage: ImageBitmap? = null | ||
private var cachedCanvas: Canvas? = null | ||
private var scopeDensity: Density? = null | ||
private var layoutDirection: LayoutDirection = LayoutDirection.Ltr | ||
private var size: IntSize = IntSize.Zero | ||
private var config: ImageBitmapConfig = ImageBitmapConfig.Argb8888 | ||
|
||
private val cacheScope = CanvasDrawScope() | ||
|
||
/** | ||
* Draw the contents of the lambda with receiver scope into an [ImageBitmap] with the provided | ||
* size. If the same size is provided across calls, the same [ImageBitmap] instance is | ||
* re-used and the contents are cleared out before drawing content in it again | ||
*/ | ||
fun drawCachedImage( | ||
config: ImageBitmapConfig, | ||
size: IntSize, | ||
density: Density, | ||
layoutDirection: LayoutDirection, | ||
block: DrawScope.() -> Unit | ||
) { | ||
this.scopeDensity = density | ||
this.layoutDirection = layoutDirection | ||
var targetImage = mCachedImage | ||
var targetCanvas = cachedCanvas | ||
if (targetImage == null || | ||
targetCanvas == null || | ||
size.width > targetImage.width || | ||
size.height > targetImage.height || | ||
this.config != config | ||
) { | ||
targetImage = ImageBitmap(size.width, size.height, config = config) | ||
targetCanvas = Canvas(targetImage) | ||
|
||
mCachedImage = targetImage | ||
cachedCanvas = targetCanvas | ||
this.config = config | ||
} | ||
this.size = size | ||
cacheScope.draw(density, layoutDirection, targetCanvas, size.toSize()) { | ||
clear() | ||
block() | ||
} | ||
targetImage.prepareToDraw() | ||
} | ||
|
||
/** | ||
* Draw the cached content into the provided [DrawScope] instance | ||
*/ | ||
fun drawInto( | ||
target: DrawScope, | ||
alpha: Float = 1.0f, | ||
colorFilter: ColorFilter? = null | ||
) { | ||
val targetImage = mCachedImage | ||
check(targetImage != null) { | ||
"drawCachedImage must be invoked first before attempting to draw the result " + | ||
"into another destination" | ||
} | ||
target.drawImage(targetImage, srcSize = size, alpha = alpha, colorFilter = colorFilter) | ||
} | ||
|
||
/** | ||
* Helper method to clear contents of the draw environment from the given bounds of the | ||
* DrawScope | ||
*/ | ||
private fun DrawScope.clear() { | ||
drawRect(color = Color.Black, blendMode = BlendMode.Clear) | ||
} | ||
} |
14 changes: 13 additions & 1 deletion
14
...rces/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageResources.skiko.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,20 @@ | ||
package org.jetbrains.compose.resources | ||
|
||
import androidx.compose.ui.graphics.ImageBitmap | ||
import androidx.compose.ui.graphics.painter.Painter | ||
import androidx.compose.ui.graphics.toComposeImageBitmap | ||
import androidx.compose.ui.unit.Density | ||
import org.jetbrains.skia.Data | ||
import org.jetbrains.skia.Image | ||
import org.jetbrains.skia.svg.SVGDOM | ||
|
||
internal actual fun ByteArray.toImageBitmap(): ImageBitmap = | ||
Image.makeFromEncoded(this).toComposeImageBitmap() | ||
Image.makeFromEncoded(this).toComposeImageBitmap() | ||
|
||
internal actual class SvgElement(val svgdom: SVGDOM) | ||
|
||
internal actual fun ByteArray.toSvgElement(): SvgElement = | ||
SvgElement(SVGDOM(Data.makeFromBytes(this))) | ||
|
||
internal actual fun SvgElement.toSvgPainter(density: Density): Painter = | ||
SvgPainter(svgdom, density) |
Oops, something went wrong.