https://github.com/jetbrains/skiko
Kotlin Multiplatform bindings to Skia
https://github.com/jetbrains/skiko
Last synced: 9 months ago
JSON representation
Kotlin Multiplatform bindings to Skia
- Host: GitHub
- URL: https://github.com/jetbrains/skiko
- Owner: JetBrains
- License: apache-2.0
- Created: 2020-07-27T10:27:13.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2025-04-22T11:01:35.000Z (9 months ago)
- Last Synced: 2025-04-22T12:22:22.940Z (9 months ago)
- Language: C++
- Homepage:
- Size: 30.4 MB
- Stars: 1,938
- Watchers: 34
- Forks: 137
- Open Issues: 30
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[](https://github.com/JetBrains/skiko/releases/latest)
# Kotlin Multiplatform library for Skia and window management #
Skiko (short for Skia for Kotlin) is the graphical library exposing significant part
of [Skia library](https://skia.org) APIs to Kotlin, along with the gluing code for rendering context.
Supported platforms:
* Kotlin/JVM on Linux(x86_64 and arm64)
* Kotlin/JVM on Windows(x86_64)
* Kotlin/JVM on macOS(x86_64 and arm64)
* Kotlin/JVM on Android(x86_64 and arm64), starting with API version 24
* Kotlin/JS + WebAssembly in browsers
* Kotlin/Native on iOS(arm64 and x64)
* Kotlin/Native on macOS (arm64 and x64)
## API documentation
See autogenerated API docs at [https://jetbrains.github.io/skiko/](https://jetbrains.github.io/skiko/)
## Using as dependency
To use in build scripts one has to compute appropriate target platform and version,
i.e. something like this
```kotlin
repositories {
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
val osName = System.getProperty("os.name")
val targetOs = when {
osName == "Mac OS X" -> "macos"
osName.startsWith("Win") -> "windows"
osName.startsWith("Linux") -> "linux"
else -> error("Unsupported OS: $osName")
}
val osArch = System.getProperty("os.arch")
val targetArch = when (osArch) {
"x86_64", "amd64" -> "x64"
"aarch64" -> "arm64"
else -> error("Unsupported arch: $osArch")
}
val version = "0.8.9" // or any more recent version
val target = "${targetOs}-${targetArch}"
dependencies {
implementation("org.jetbrains.skiko:skiko-awt-runtime-$target:$version")
}
```
Simple example for Kotlin/JVM
```kotlin
fun main() {
val skiaLayer = SkiaLayer()
skiaLayer.renderDelegate = SkiaLayerRenderDelegate(skiaLayer, object : SkikoRenderDelegate {
val paint = Paint().apply {
color = Color.RED
}
override fun onRender(canvas: Canvas, width: Int, height: Int, nanoTime: Long) {
canvas.clear(Color.CYAN)
val ts = nanoTime / 5_000_000
canvas.drawCircle( (ts % width).toFloat(), (ts % height).toFloat(), 20f, paint )
}
})
SwingUtilities.invokeLater {
val window = JFrame("Skiko example").apply {
defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
preferredSize = Dimension(800, 600)
}
skiaLayer.attachTo(window.contentPane)
skiaLayer.needRedraw()
window.pack()
window.isVisible = true
}
}
```
Simple example for iOS
```kotlin
fun main() {
val args = emptyArray()
memScoped {
val argc = args.size + 1
val argv = (arrayOf("skikoApp") + args).map { it.cstr.ptr }.toCValues()
autoreleasepool {
UIApplicationMain(argc, argv, null, NSStringFromClass(SkikoAppDelegate))
}
}
}
class SkikoAppDelegate : UIResponder, UIApplicationDelegateProtocol {
companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta
@ObjCObjectBase.OverrideInit
constructor() : super()
private var _window: UIWindow? = null
override fun window() = _window
override fun setWindow(window: UIWindow?) {
_window = window
}
override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map?): Boolean {
window = UIWindow(frame = UIScreen.mainScreen.bounds)
window!!.rootViewController = SkikoViewController(
SkikoUIView(
SkiaLayer().apply {
renderDelegate = SkiaLayerRenderDelegate(skiaLayer, object : SkikoRenderDelegate {
val paint = Paint().apply { color = Color.RED }
override fun onRender(canvas: Canvas, width: Int, height: Int, nanoTime: Long) {
canvas.clear(Color.CYAN)
val ts = nanoTime / 5_000_000
canvas.drawCircle( (ts % width).toFloat(), (ts % height).toFloat(), 20f, paint )
}
})
}
)
)
window!!.makeKeyAndVisible()
return true
}
}
```
See this [sample](/samples/SkiaMultiplatformSample) for complete example.