Unverified Commit e3b0ef8d authored by Igor Demin's avatar Igor Demin Committed by GitHub

Refactorings from the AWT Font PR (#729)

* Refactoring from AWT Font PR

Thanks, @rock3r, for refactorings! I extracted them from the AWT font PR (they were reverted in https://github.com/JetBrains/skiko/pull/639/commits/53f00c7d6be5ac0834ba4b4c3b9b4e3ea5cb0f10)

- fix formatting
- fix comments
- split CI steps

I am not sure about mikepenz/action-junit-report. Let's remove it for now (otherwise it should be investigated from functionality and security perspective)

* Refactoring from AWT Font PR

Thanks, @rock3r, for refactorings! I extracted them from the AWT font PR (they were reverted in https://github.com/JetBrains/skiko/pull/639/commits/53f00c7d6be5ac0834ba4b4c3b9b4e3ea5cb0f10)

- fix formatting
- fix comments
- split CI steps

I am not sure about mikepenz/action-junit-report. Let's remove it for now (otherwise it should be investigated from functionality and security perspective)

Also, removed implementation("pl.pragmatists:JUnitParams:1.1.1"), as it isn't used.
parent 02683bcd
# Default Skiko CI # Default Skiko CI
name: CI name: CI
# Controls when the action will run.
on: on:
# Triggers the workflow on push or pull request events but only for the master branch
push: push:
branches: [ master ] branches: [ master ]
# TODO: temporary for faster tests, restore! # TODO: temporary for faster tests, restore!
pull_request: pull_request:
branches: [ master ] branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch: workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs: jobs:
macos: macos:
# The type of runner that the job will run on
runs-on: macos-11 runs-on: macos-11
# Steps represent a sequence of tasks that will be executed as part of the job
steps: steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3
- uses: actions/checkout@v2 name: 'Check out code'
- uses: actions/setup-java@v2
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '11' java-version: '11'
cache: 'gradle'
- shell: bash
name: 'Compile and run AWT tests'
run: ./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:awtTest
- shell: bash
name: 'Compile and run macOS x64 tests'
run: ./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:macosX64Test
- shell: bash - shell: bash
name: 'Publish to Maven Local, check AWT sample'
run: | run: |
./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:awtTest
./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:macosX64Test
./gradlew --stacktrace --info -Pskiko.native.enabled=true :skiko:publishToMavenLocal ./gradlew --stacktrace --info -Pskiko.native.enabled=true :skiko:publishToMavenLocal
./gradlew --stacktrace --info :SkiaAwtSample:installDist # check AWT sample works ./gradlew --stacktrace --info :SkiaAwtSample:installDist
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
name: 'Save test results as artifact'
if: always() if: always()
with: with:
name: test-reports-macos name: test-reports-macos
...@@ -40,24 +47,34 @@ jobs: ...@@ -40,24 +47,34 @@ jobs:
retention-days: 5 retention-days: 5
ios: ios:
# The type of runner that the job will run on
runs-on: macos-11 runs-on: macos-11
# Steps represent a sequence of tasks that will be executed as part of the job
steps: steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3
- uses: actions/checkout@v2 name: 'Check out code'
- uses: actions/setup-java@v2
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '11' java-version: '11'
cache: 'gradle'
- shell: bash - shell: bash
run: | name: 'Compile and run iOS x64 tests'
./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:iosX64Test run: ./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:iosX64Test
# iosSimulatorArm64Test will build the binary but the tests will be skipped due to X64 host machine # iosSimulatorArm64Test will build the binary but the tests will be skipped due to X64 host machine
./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:iosSimulatorArm64Test - shell: bash
./gradlew --stacktrace --info -Pskiko.native.enabled=true :skiko:publishToMavenLocal name: 'Compile iOS arm64 tests'
run: ./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:iosSimulatorArm64Test
# TODO run iOS specific tests on iPhone simulator # TODO run iOS specific tests on iPhone simulator
- uses: actions/upload-artifact@v2 - shell: bash
name: 'Publish to Maven Local'
run: ./gradlew --stacktrace --info -Pskiko.native.enabled=true :skiko:publishToMavenLocal
- uses: actions/upload-artifact@v3
name: 'Save test results as artifact'
if: always() if: always()
with: with:
name: test-reports-macos name: test-reports-macos
...@@ -66,21 +83,28 @@ jobs: ...@@ -66,21 +83,28 @@ jobs:
linux: linux:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
# Steps represent a sequence of tasks that will be executed as part of the job
steps: steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3
- uses: actions/checkout@v2 name: 'Check out code'
- uses: actions/setup-java@v2
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '11' java-version: '11'
cache: 'gradle'
- uses: nttld/setup-ndk@v1 - uses: nttld/setup-ndk@v1
name: 'Set up Android NDK'
id: setup-ndk id: setup-ndk
with: with:
ndk-version: r21e ndk-version: r21e
- uses: android-actions/setup-android@v2 - uses: android-actions/setup-android@v2
# Runs a set of commands using the runners shell name: 'Set up Android SDK'
- shell: bash - shell: bash
name: 'Set up Linux build environment'
env: env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
run: | run: |
...@@ -96,23 +120,31 @@ jobs: ...@@ -96,23 +120,31 @@ jobs:
sudo update-alternatives --config gcc sudo update-alternatives --config gcc
sudo apt-get install ninja-build fontconfig libfontconfig1-dev libglu1-mesa-dev libxrandr-dev libdbus-1-dev zip xvfb -y sudo apt-get install ninja-build fontconfig libfontconfig1-dev libglu1-mesa-dev libxrandr-dev libdbus-1-dev zip xvfb -y
sudo Xvfb :0 -screen 0 1280x720x24 & sudo Xvfb :0 -screen 0 1280x720x24 &
- run: |
# Test Linux native - shell: bash
name: 'Compile and run Linux x64 tests'
run: |
export DISPLAY=:0 export DISPLAY=:0
./gradlew --no-daemon --stacktrace --info -Pskiko.native.enabled=true -Pkotlin.native.cacheKind.linuxX64=none -Pskiko.test.onci=true :skiko:linuxX64Test ./gradlew --no-daemon --stacktrace --info -Pskiko.native.enabled=true -Pkotlin.native.cacheKind.linuxX64=none -Pskiko.test.onci=true :skiko:linuxX64Test
- run: |
# Test Linux AWT - shell: bash
name: 'Compile and run AWT tests'
run: |
export DISPLAY=:0 export DISPLAY=:0
./gradlew --no-daemon --stacktrace --info -Pskiko.native.enabled=true -Pkotlin.native.cacheKind.linuxX64=none -Pskiko.test.onci=true :skiko:awtTest ./gradlew --no-daemon --stacktrace --info -Pskiko.native.enabled=true -Pkotlin.native.cacheKind.linuxX64=none -Pskiko.test.onci=true :skiko:awtTest
timeout-minutes: 25 timeout-minutes: 25
- env:
- shell: bash
name: 'Publish to Maven Local, check AWT sample'
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
run: | run: |
# Test publishToMavenLocal
./gradlew --no-daemon --stacktrace --info -Pkotlin.native.cacheKind.linuxX64=none :skiko:publishToMavenLocal ./gradlew --no-daemon --stacktrace --info -Pkotlin.native.cacheKind.linuxX64=none :skiko:publishToMavenLocal
./gradlew --no-daemon --stacktrace --info :SkiaAwtSample:installDist # check jvm sample works ./gradlew --no-daemon --stacktrace --info :SkiaAwtSample:installDist
./gradlew --no-daemon -Pskiko.android.enabled=true :skiko:publishSkikoJvmRuntimeAndroidX64PublicationToMavenLocal :skiko:publishSkikoJvmRuntimeAndroidArm64PublicationToMavenLocal :skiko:publishAndroidPublicationToMavenLocal ./gradlew --no-daemon -Pskiko.android.enabled=true :skiko:publishSkikoJvmRuntimeAndroidX64PublicationToMavenLocal :skiko:publishSkikoJvmRuntimeAndroidArm64PublicationToMavenLocal :skiko:publishAndroidPublicationToMavenLocal
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
name: 'Save test results as artifact'
if: always() if: always()
with: with:
name: test-reports-linux name: test-reports-linux
...@@ -121,16 +153,19 @@ jobs: ...@@ -121,16 +153,19 @@ jobs:
js: js:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
# Steps represent a sequence of tasks that will be executed as part of the job
steps: steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3
- uses: actions/checkout@v2 name: 'Check out code'
- uses: actions/setup-java@v2
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '11' java-version: '11'
# Runs a set of commands using the runners shell cache: 'gradle'
- shell: bash - shell: bash
name: 'Set up JS build environment'
run: | run: |
cd ./skiko cd ./skiko
sudo apt-get update -y sudo apt-get update -y
...@@ -146,11 +181,19 @@ jobs: ...@@ -146,11 +181,19 @@ jobs:
fi fi
./emsdk install 2.0.29 ./emsdk install 2.0.29
./emsdk activate 2.0.29 ./emsdk activate 2.0.29
source ./emsdk_env.sh - shell: bash
cd .. name: 'Compile and run JS tests'
./gradlew --stacktrace --info -Pskiko.wasm.enabled=true -Pskiko.test.onci=true jsTest run: |
./gradlew --stacktrace --info -Pskiko.wasm.enabled=true publishSkikoWasmRuntimePublicationToMavenLocal source "$(pwd)/skiko/emsdk/emsdk_env.sh"
- uses: actions/upload-artifact@v2 ./gradlew --stacktrace --info -Pskiko.wasm.enabled=true -Pskiko.test.onci=true :skiko:jsTest
- shell: bash
name: 'Publish WASM runtime to Maven Local'
run: |
source "$(pwd)/skiko/emsdk/emsdk_env.sh"
./gradlew --stacktrace --info -Pskiko.wasm.enabled=true :skiko:publishSkikoWasmRuntimePublicationToMavenLocal
- uses: actions/upload-artifact@v3
name: 'Save test results as artifact'
if: always() if: always()
with: with:
name: test-reports-js name: test-reports-js
...@@ -160,19 +203,32 @@ jobs: ...@@ -160,19 +203,32 @@ jobs:
windows: windows:
runs-on: windows-2019 runs-on: windows-2019
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
name: 'Check out code'
- uses: microsoft/setup-msbuild@v1 - uses: microsoft/setup-msbuild@v1
- uses: ilammy/msvc-dev-cmd@v1 - uses: ilammy/msvc-dev-cmd@v1
- uses: actions/setup-java@v2
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '11' java-version: '11'
cache: 'gradle'
- shell: bash - shell: bash
name: 'Compile and run AWT tests'
run: ./gradlew --stacktrace --info -Pskiko.test.onci=true :skiko:awtTest
- shell: bash
name: 'Publish to Maven Local, check AWT sample'
run: | run: |
./gradlew --stacktrace --info -Pskiko.test.onci=true :skiko:awtTest
./gradlew --stacktrace --info :skiko:publishToMavenLocal ./gradlew --stacktrace --info :skiko:publishToMavenLocal
./gradlew --stacktrace --info :SkiaAwtSample:installDist # check jvm sample works ./gradlew --stacktrace --info :SkiaAwtSample:installDist
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
name: 'Save test results as artifact'
if: always() if: always()
with: with:
name: test-reports-windows name: test-reports-windows
......
# Build Skiko documentation # Build Skiko documentation
name: Doc name: Doc
# Controls when the action will run.
on: on:
# Triggers the workflow on push or pull request events but only for the master branch
push: push:
branches: [ master ] branches: [ master ]
# Temporary, for testing. Remove! # Temporary, for testing. Remove!
#pull_request: #pull_request:
# branches: [ master ] # branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch: workflow_dispatch:
# See https://github.com/marketplace/actions/deploy-to-github-pages
jobs: jobs:
dokka: dokka:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: actions/setup-java@v2 name: 'Check out code'
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with: with:
distribution: 'adopt' distribution: 'adopt'
java-version: '11' java-version: '11'
- name: Build docs cache: 'gradle'
- name: 'Build Dokka documentation'
run: bash -c 'JAVA_OPTS="-Xmx4g" ./gradlew --no-daemon -Pskiko.native.enabled=true -Pskiko.wasm.enabled=true -Pskiko.android.enabled=true :skiko:dokkaHtml' run: bash -c 'JAVA_OPTS="-Xmx4g" ./gradlew --no-daemon -Pskiko.native.enabled=true -Pskiko.wasm.enabled=true -Pskiko.android.enabled=true :skiko:dokkaHtml'
- name: Publish documentation
- name: 'Publish documentation'
uses: JamesIves/github-pages-deploy-action@releases/v3 uses: JamesIves/github-pages-deploy-action@releases/v3
with: with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
......
...@@ -4,3 +4,6 @@ build ...@@ -4,3 +4,6 @@ build
local.properties local.properties
.DS_Store .DS_Store
dependencies/ dependencies/
# Screenshot test actual files
**/src/**/screenshots/*_actual.png
...@@ -4,16 +4,20 @@ ...@@ -4,16 +4,20 @@
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" /> <option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="awtTest -Dskiko.test.ui.enabled=true -Dskiko.test.ui.renderApi=all" /> <option name="scriptParameters" value="-Dskiko.test.ui.enabled=true -Dskiko.test.ui.renderApi=all" />
<option name="taskDescriptions"> <option name="taskDescriptions">
<list /> <list />
</option> </option>
<option name="taskNames"> <option name="taskNames">
<list /> <list>
<option value=":awtTest" />
</list>
</option> </option>
<option name="vmOptions" /> <option name="vmOptions" />
</ExternalSystemSettings> </ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled> <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" /> <method v="2" />
</configuration> </configuration>
</component> </component>
\ No newline at end of file
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</option> </option>
<option name="taskNames"> <option name="taskNames">
<list> <list>
<option value="publishToMavenLocal" /> <option value=":publishToMavenLocal" />
</list> </list>
</option> </option>
<option name="vmOptions" value="" /> <option name="vmOptions" value="" />
......
import de.undercouch.gradle.tasks.download.Download import de.undercouch.gradle.tasks.download.Download
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.crypto.checksum.Checksum import org.gradle.crypto.checksum.Checksum
import org.gradle.api.tasks.testing.AbstractTestTask
import org.jetbrains.compose.internal.publishing.MavenCentralProperties import org.jetbrains.compose.internal.publishing.MavenCentralProperties
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTool import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTool
import org.jetbrains.kotlin.konan.target.KonanTarget
plugins { plugins {
kotlin("multiplatform") version "1.8.20" kotlin("multiplatform") version "1.8.20"
...@@ -911,7 +909,7 @@ fun createLinkJvmBindings( ...@@ -911,7 +909,7 @@ fun createLinkJvmBindings(
val skiaBinDir = skiaJvmBindingsDir.get().absolutePath + "/" + skiaBinSubdir val skiaBinDir = skiaJvmBindingsDir.get().absolutePath + "/" + skiaBinSubdir
val osFlags: Array<String> val osFlags: Array<String>
libFiles = fileTree(skiaJvmBindingsDir.map { it.resolve(skiaBinSubdir)}) { libFiles = fileTree(skiaJvmBindingsDir.map { it.resolve(skiaBinSubdir) }) {
include(if (targetOs.isWindows) "*.lib" else "*.a") include(if (targetOs.isWindows) "*.lib" else "*.a")
} }
...@@ -979,7 +977,8 @@ fun createLinkJvmBindings( ...@@ -979,7 +977,8 @@ fun createLinkJvmBindings(
libDirs.set(windowsSdkPaths.libDirs) libDirs.set(windowsSdkPaths.libDirs)
osFlags = mutableListOf<String>().apply { osFlags = mutableListOf<String>().apply {
addAll(buildType.msvcLinkerFlags) addAll(buildType.msvcLinkerFlags)
addAll(arrayOf( addAll(
arrayOf(
"/NOLOGO", "/NOLOGO",
"/DLL", "/DLL",
"Advapi32.lib", "Advapi32.lib",
...@@ -988,7 +987,8 @@ fun createLinkJvmBindings( ...@@ -988,7 +987,8 @@ fun createLinkJvmBindings(
"opengl32.lib", "opengl32.lib",
"shcore.lib", "shcore.lib",
"user32.lib", "user32.lib",
)) )
)
if (buildType == SkiaBuildType.DEBUG) add("dxgi.lib") if (buildType == SkiaBuildType.DEBUG) add("dxgi.lib")
}.toTypedArray() }.toTypedArray()
} }
...@@ -1010,7 +1010,7 @@ fun createLinkJvmBindings( ...@@ -1010,7 +1010,7 @@ fun createLinkJvmBindings(
} }
} }
flags.set(listOf(*osFlags)) flags.set(listOf(*osFlags))
} }
fun KotlinTarget.generateVersion( fun KotlinTarget.generateVersion(
targetOs: OS, targetOs: OS,
...@@ -1034,11 +1034,12 @@ fun KotlinTarget.generateVersion( ...@@ -1034,11 +1034,12 @@ fun KotlinTarget.generateVersion(
val target = "${targetOs.id}-${targetArch.id}" val target = "${targetOs.id}-${targetArch.id}"
val skiaTag = project.property("dependencies.skia.$target") as String val skiaTag = project.property("dependencies.skia.$target") as String
File(out).writeText(""" File(out).writeText(
"""
package org.jetbrains.skiko package org.jetbrains.skiko
object Version { object Version {
val skiko = "${skiko.deployVersion}" val skiko = "${skiko.deployVersion}"
val skia = "${skiaTag}" val skia = "$skiaTag"
} }
""".trimIndent() """.trimIndent()
) )
...@@ -1135,7 +1136,7 @@ tasks.withType<Test>().configureEach { ...@@ -1135,7 +1136,7 @@ tasks.withType<Test>().configureEach {
options { options {
val dir = skikoRuntimeDirForTests.map { it.destinationDir }.get() val dir = skikoRuntimeDirForTests.map { it.destinationDir }.get()
systemProperty("skiko.library.path", dir) systemProperty("skiko.library.path", dir)
val jar = skikoJarForTests.get().outputs.files.files.single { it.name.endsWith(".jar")} val jar = skikoJarForTests.get().outputs.files.files.single { it.name.endsWith(".jar") }
systemProperty("skiko.jar.path", jar.absolutePath) systemProperty("skiko.jar.path", jar.absolutePath)
systemProperty("skiko.test.screenshots.dir", File(project.projectDir, "src/jvmTest/screenshots").absolutePath) systemProperty("skiko.test.screenshots.dir", File(project.projectDir, "src/jvmTest/screenshots").absolutePath)
...@@ -1144,7 +1145,10 @@ tasks.withType<Test>().configureEach { ...@@ -1144,7 +1145,10 @@ tasks.withType<Test>().configureEach {
val testingOnCI = System.getProperty("skiko.test.onci", "false").toBoolean() val testingOnCI = System.getProperty("skiko.test.onci", "false").toBoolean()
val canRunPerformanceTests = testingOnCI val canRunPerformanceTests = testingOnCI
val canRunUiTests = testingOnCI || System.getProperty("os.name") != "Mac OS X" val canRunUiTests = testingOnCI || System.getProperty("os.name") != "Mac OS X"
systemProperty("skiko.test.performance.enabled", System.getProperty("skiko.test.performance.enabled", canRunPerformanceTests.toString())) systemProperty(
"skiko.test.performance.enabled",
System.getProperty("skiko.test.performance.enabled", canRunPerformanceTests.toString())
)
systemProperty("skiko.test.ui.enabled", System.getProperty("skiko.test.ui.enabled", canRunUiTests.toString())) systemProperty("skiko.test.ui.enabled", System.getProperty("skiko.test.ui.enabled", canRunUiTests.toString()))
systemProperty("skiko.test.ui.renderApi", System.getProperty("skiko.test.ui.renderApi", "all")) systemProperty("skiko.test.ui.renderApi", System.getProperty("skiko.test.ui.renderApi", "all"))
......
...@@ -13,8 +13,8 @@ import javax.swing.UIManager ...@@ -13,8 +13,8 @@ import javax.swing.UIManager
actual fun setSystemLookAndFeel() = UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) actual fun setSystemLookAndFeel() = UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())
internal actual fun makeDefaultRenderFactory(): RenderFactory { internal actual fun makeDefaultRenderFactory(): RenderFactory =
return object : RenderFactory { object : RenderFactory {
override fun createRedrawer( override fun createRedrawer(
layer: SkiaLayer, layer: SkiaLayer,
renderApi: GraphicsApi, renderApi: GraphicsApi,
...@@ -36,10 +36,9 @@ internal actual fun makeDefaultRenderFactory(): RenderFactory { ...@@ -36,10 +36,9 @@ internal actual fun makeDefaultRenderFactory(): RenderFactory {
GraphicsApi.SOFTWARE_FAST -> LinuxSoftwareRedrawer(layer, analytics, properties) GraphicsApi.SOFTWARE_FAST -> LinuxSoftwareRedrawer(layer, analytics, properties)
else -> LinuxOpenGLRedrawer(layer, analytics, properties) else -> LinuxOpenGLRedrawer(layer, analytics, properties)
} }
OS.Android, OS.JS, OS.Ios -> throw UnsupportedOperationException("The awt target doesn't support $hostOs") OS.Android, OS.JS, OS.Ios -> throw UnsupportedOperationException("The AWT target doesn't support $hostOs")
} }
} }
}
internal actual fun URIHandler_openUri(uri: String) { internal actual fun URIHandler_openUri(uri: String) {
Desktop.getDesktop().browse(URI(uri)) Desktop.getDesktop().browse(URI(uri))
...@@ -56,6 +55,7 @@ private val systemClipboard by lazy { ...@@ -56,6 +55,7 @@ private val systemClipboard by lazy {
internal actual fun ClipboardManager_setText(text: String) { internal actual fun ClipboardManager_setText(text: String) {
systemClipboard?.setContents(StringSelection(text), null) systemClipboard?.setContents(StringSelection(text), null)
} }
internal actual fun ClipboardManager_getText(): String? { internal actual fun ClipboardManager_getText(): String? {
return try { return try {
systemClipboard?.getData(DataFlavor.stringFlavor) as String? systemClipboard?.getData(DataFlavor.stringFlavor) as String?
......
package org.jetbrains.skia package org.jetbrains.skia
import org.jetbrains.skia.impl.InteropPointer import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.RefCnt
import org.jetbrains.skia.impl.Stats
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skia.impl.interopScope
import org.jetbrains.skia.impl.reachabilityBarrier
import org.jetbrains.skia.impl.withStringResult
open class FontMgr : RefCnt { open class FontMgr : RefCnt {
companion object { companion object {
...@@ -27,8 +20,8 @@ open class FontMgr : RefCnt { ...@@ -27,8 +20,8 @@ open class FontMgr : RefCnt {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
fun getFamilyName(index: Int): String { fun getFamilyName(index: Int): String =
return try { try {
Stats.onNativeCall() Stats.onNativeCall()
withStringResult { withStringResult {
_nGetFamilyName(_ptr, index) _nGetFamilyName(_ptr, index)
...@@ -36,59 +29,55 @@ open class FontMgr : RefCnt { ...@@ -36,59 +29,55 @@ open class FontMgr : RefCnt {
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
}
fun makeStyleSet(index: Int): FontStyleSet? { fun makeStyleSet(index: Int): FontStyleSet? =
return try { try {
Stats.onNativeCall() Stats.onNativeCall()
val ptr = _nMakeStyleSet(_ptr, index) val ptr = _nMakeStyleSet(_ptr, index)
if (ptr == NullPointer) null else FontStyleSet(ptr) if (ptr == NullPointer) null else FontStyleSet(ptr)
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
}
/** /**
* The caller must call [.close] on the returned object. * The caller must call [close] on the returned object.
* Never returns null; will return an empty set if the name is not found. * Never returns `null`; will return an empty set if the name is not found.
* *
* Passing null as the parameter will return the default system family. * Passing `null` as the parameter will return the default system family.
* Note that most systems don't have a default system family, so passing null will often * Note that most systems don't have a default system family, so passing
* result in the empty set. * `null` will often result in the empty set.
* *
* It is possible that this will return a style set not accessible from * It is possible that this will return a style set not accessible from
* [.makeStyleSet] due to hidden or auto-activated fonts. * [makeStyleSet] due to hidden or auto-activated fonts.
*/ */
fun matchFamily(familyName: String?): FontStyleSet { fun matchFamily(familyName: String?): FontStyleSet =
return try { try {
Stats.onNativeCall() Stats.onNativeCall()
interopScope { FontStyleSet(_nMatchFamily(_ptr, toInterop(familyName))) } interopScope { FontStyleSet(_nMatchFamily(_ptr, toInterop(familyName))) }
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
}
/** /**
* Find the closest matching typeface to the specified familyName and style * Find the closest matching typeface to the specified [familyName] and [style]
* and return a ref to it. The caller must call [.close] on the returned * and return it. The caller must call [close] on the returned
* object. Will return null if no 'good' match is found. * object. Will return `null` if no 'good' match is found.
* *
* Passing null as the parameter for `familyName` will return the * Passing `null` as the value for [familyName] will return the
* default system font. * default system font.
* *
* It is possible that this will return a style set not accessible from * It is possible that this will return a style set not accessible from
* [.makeStyleSet] or [.matchFamily] due to hidden or * [makeStyleSet] or [matchFamily] due to hidden or
* auto-activated fonts. * auto-activated fonts.
*/ */
fun matchFamilyStyle(familyName: String?, style: FontStyle): Typeface? { fun matchFamilyStyle(familyName: String?, style: FontStyle): Typeface? =
return try { try {
Stats.onNativeCall() Stats.onNativeCall()
val ptr = interopScope { _nMatchFamilyStyle(_ptr, toInterop(familyName), style._value) } val ptr = interopScope { _nMatchFamilyStyle(_ptr, toInterop(familyName), style._value) }
if (ptr == NullPointer) null else Typeface(ptr) if (ptr == NullPointer) null else Typeface(ptr)
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
}
fun matchFamiliesStyle(families: Array<String?>, style: FontStyle): Typeface? { fun matchFamiliesStyle(families: Array<String?>, style: FontStyle): Typeface? {
for (family in families) { for (family in families) {
...@@ -103,13 +92,13 @@ open class FontMgr : RefCnt { ...@@ -103,13 +92,13 @@ open class FontMgr : RefCnt {
* Note that bcp47 is a combination of ISO 639, 15924, and 3166-1 codes, * Note that bcp47 is a combination of ISO 639, 15924, and 3166-1 codes,
* so it is fine to just pass a ISO 639 here. * so it is fine to just pass a ISO 639 here.
* *
* Will return null if no family can be found for the character * Will return `null` if no family can be found for the character
* in the system fallback. * in the system fallback.
* *
* Passing `null` as the parameter for `familyName` will return the * Passing `null` as the value for [familyName] will return the
* default system font. * default system font.
* *
* bcp47[0] is the least significant fallback, bcp47[bcp47.length-1] is the * `bcp47[0]` is the least significant fallback, `bcp47[bcp47.length-1]` is the
* most significant. If no specified bcp47 codes match, any font with the * most significant. If no specified bcp47 codes match, any font with the
* requested character will be matched. * requested character will be matched.
*/ */
...@@ -118,8 +107,8 @@ open class FontMgr : RefCnt { ...@@ -118,8 +107,8 @@ open class FontMgr : RefCnt {
style: FontStyle, style: FontStyle,
bcp47: Array<String>?, bcp47: Array<String>?,
character: Int character: Int
): Typeface? { ): Typeface? =
return try { try {
Stats.onNativeCall() Stats.onNativeCall()
val ptr = interopScope { val ptr = interopScope {
_nMatchFamilyStyleCharacter( _nMatchFamilyStyleCharacter(
...@@ -135,7 +124,6 @@ open class FontMgr : RefCnt { ...@@ -135,7 +124,6 @@ open class FontMgr : RefCnt {
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
}
fun matchFamiliesStyleCharacter( fun matchFamiliesStyleCharacter(
families: Array<String?>, families: Array<String?>,
...@@ -152,11 +140,11 @@ open class FontMgr : RefCnt { ...@@ -152,11 +140,11 @@ open class FontMgr : RefCnt {
/** /**
* Create a typeface for the specified data and TTC index (pass 0 for none) * Create a typeface for the specified data and TTC index (pass 0 for none)
* or null if the data is not recognized. The caller must call [.close] on * or null if the data is not recognized. The caller must call [close] on
* the returned object if it is not null. * the returned object if it is not null.
*/ */
fun makeFromData(data: Data?, ttcIndex: Int = 0): Typeface? { fun makeFromData(data: Data?, ttcIndex: Int = 0): Typeface? =
return try { try {
Stats.onNativeCall() Stats.onNativeCall()
val ptr = val ptr =
_nMakeFromData(_ptr, getPtr(data), ttcIndex) _nMakeFromData(_ptr, getPtr(data), ttcIndex)
...@@ -165,7 +153,6 @@ open class FontMgr : RefCnt { ...@@ -165,7 +153,6 @@ open class FontMgr : RefCnt {
reachabilityBarrier(this) reachabilityBarrier(this)
reachabilityBarrier(data) reachabilityBarrier(data)
} }
}
internal constructor(ptr: NativePointer) : super(ptr) internal constructor(ptr: NativePointer) : super(ptr)
......
...@@ -32,9 +32,7 @@ class FontStyle { ...@@ -32,9 +32,7 @@ class FontStyle {
return FontStyle(weight, width, slant) return FontStyle(weight, width, slant)
} }
override fun toString(): String { override fun toString(): String = "FontStyle(weight=$weight, width=$width, slant=$slant)"
return "FontStyle(weight=$weight, width=$width, slant=$slant)"
}
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other === this) return true if (other === this) return true
......
package org.jetbrains.skia package org.jetbrains.skia
import org.jetbrains.skia.impl.InteropPointer import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.Native
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.RefCnt
import org.jetbrains.skia.impl.Stats
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skia.impl.interopScope
import org.jetbrains.skia.impl.reachabilityBarrier
import org.jetbrains.skia.impl.withNullableResult
import org.jetbrains.skia.impl.withResult
import org.jetbrains.skia.impl.withStringResult
class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
companion object { companion object {
...@@ -401,6 +391,8 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -401,6 +391,8 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
override fun toString() = "Typeface(familyName='$familyName', fontStyle=$fontStyle, uniqueId=$uniqueId)"
} }
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetUniqueId") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetUniqueId")
......
...@@ -6,8 +6,8 @@ import kotlin.coroutines.Continuation ...@@ -6,8 +6,8 @@ import kotlin.coroutines.Continuation
import kotlin.coroutines.resume import kotlin.coroutines.resume
/** /**
* Behaves as Channel<Unit>(Channel.RENDEZVOUS), but with ability to send value to all current consumers * Behaves as `Channel<Unit>(Channel.RENDEZVOUS)`, but with ability to send a value to all current consumers
* (which await on `receive` method). * (which will await on `receive` method).
*/ */
internal class RendezvousBroadcastChannel<T> { internal class RendezvousBroadcastChannel<T> {
private val onRequest = Channel<Unit>(Channel.CONFLATED) private val onRequest = Channel<Unit>(Channel.CONFLATED)
...@@ -32,7 +32,7 @@ internal class RendezvousBroadcastChannel<T> { ...@@ -32,7 +32,7 @@ internal class RendezvousBroadcastChannel<T> {
} }
/** /**
* Wait when the producer will send a value and return it. * Wait until the producer sends a value, and returns it.
* *
* Can be called concurrently from multiple threads. * Can be called concurrently from multiple threads.
*/ */
......
...@@ -4,10 +4,8 @@ import org.jetbrains.skia.impl.use ...@@ -4,10 +4,8 @@ import org.jetbrains.skia.impl.use
import org.jetbrains.skia.tests.assertCloseEnough import org.jetbrains.skia.tests.assertCloseEnough
import org.jetbrains.skia.tests.assertContentCloseEnough import org.jetbrains.skia.tests.assertContentCloseEnough
import org.jetbrains.skia.tests.makeFromResource import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skiko.KotlinBackend
import org.jetbrains.skiko.OS import org.jetbrains.skiko.OS
import org.jetbrains.skiko.hostOs import org.jetbrains.skiko.hostOs
import org.jetbrains.skiko.kotlinBackend
import org.jetbrains.skiko.tests.runTest import org.jetbrains.skiko.tests.runTest
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertContentEquals import kotlin.test.assertContentEquals
......
...@@ -3,12 +3,12 @@ package org.jetbrains.skia ...@@ -3,12 +3,12 @@ package org.jetbrains.skia
import org.jetbrains.skia.tests.assertCloseEnough import org.jetbrains.skia.tests.assertCloseEnough
import org.jetbrains.skia.tests.assertContentCloseEnough import org.jetbrains.skia.tests.assertContentCloseEnough
import org.jetbrains.skia.tests.makeFromResource import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skiko.KotlinBackend
import org.jetbrains.skiko.kotlinBackend
import org.jetbrains.skiko.tests.runTest import org.jetbrains.skiko.tests.runTest
import kotlin.math.cos import kotlin.math.cos
import kotlin.math.sin import kotlin.math.sin
import kotlin.test.* import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals
class TextBlobBuilderTest { class TextBlobBuilderTest {
......
...@@ -3,8 +3,6 @@ package org.jetbrains.skiko ...@@ -3,8 +3,6 @@ package org.jetbrains.skiko
import org.jetbrains.skia.* import org.jetbrains.skia.*
import org.jetbrains.skia.tests.assertCloseEnough import org.jetbrains.skia.tests.assertCloseEnough
import org.jetbrains.skia.tests.makeFromResource import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skiko.tests.SkipJsTarget
import org.jetbrains.skiko.tests.SkipNativeTarget
import org.jetbrains.skiko.tests.runTest import org.jetbrains.skiko.tests.runTest
import kotlin.test.* import kotlin.test.*
......
...@@ -12,8 +12,8 @@ object Library { ...@@ -12,8 +12,8 @@ object Library {
private val skikoLibraryPath = System.getProperty(SKIKO_LIBRARY_PATH_PROPERTY) private val skikoLibraryPath = System.getProperty(SKIKO_LIBRARY_PATH_PROPERTY)
private var copyDir: File? = null private var copyDir: File? = null
// Same native library cannot be loaded in several classloaders, so we have to clone // A native library cannot be loaded in several classloaders, so we have to clone
// native library to allow Skiko loading to work properly in complex cases, i.e. // the native library to allow Skiko loading to work properly in complex cases, i.e.,
// several IDEA plugins. // several IDEA plugins.
private fun loadLibraryOrCopy(library: File) { private fun loadLibraryOrCopy(library: File) {
try { try {
...@@ -49,8 +49,8 @@ object Library { ...@@ -49,8 +49,8 @@ object Library {
// This function does the following: on request to load given resource, // This function does the following: on request to load given resource,
// it checks if resource with given name is found in content-derived directory // it checks if resource with given name is found in content-derived directory
// in Skiko's home, and if not - unpacks it. Also, it could load additional // in Skiko's home, and if not - unpacks it. It could also load additional
// localization resource on platforms where it is needed. // localization resources, on platforms where it is needed.
@Synchronized @Synchronized
fun load() { fun load() {
if (!loaded.compareAndSet(false, true)) return if (!loaded.compareAndSet(false, true)) return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment