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
name: CI
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
# TODO: temporary for faster tests, restore!
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
macos:
# The type of runner that the job will run on
macos:
runs-on: macos-11
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
- uses: actions/checkout@v3
name: 'Check out code'
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with:
distribution: 'adopt'
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
name: 'Publish to Maven Local, check AWT sample'
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 :SkiaAwtSample:installDist # check AWT sample works
- uses: actions/upload-artifact@v2
./gradlew --stacktrace --info :SkiaAwtSample:installDist
- uses: actions/upload-artifact@v3
name: 'Save test results as artifact'
if: always()
with:
name: test-reports-macos
path: ./skiko/build/reports/tests
retention-days: 5
ios:
# The type of runner that the job will run on
ios:
runs-on: macos-11
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
- uses: actions/checkout@v3
name: 'Check out code'
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with:
distribution: 'adopt'
java-version: '11'
cache: 'gradle'
- shell: bash
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
./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:iosSimulatorArm64Test
./gradlew --stacktrace --info -Pskiko.native.enabled=true :skiko:publishToMavenLocal
# TODO run iOS specific tests on iPhone simulator
- uses: actions/upload-artifact@v2
name: 'Compile and run iOS x64 tests'
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
- shell: bash
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
- 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()
with:
name: test-reports-macos
path: ./skiko/build/reports/tests
retention-days: 5
linux:
linux:
runs-on: ubuntu-20.04
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
- uses: actions/checkout@v3
name: 'Check out code'
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with:
distribution: 'adopt'
java-version: '11'
cache: 'gradle'
- uses: nttld/setup-ndk@v1
name: 'Set up Android NDK'
id: setup-ndk
with:
ndk-version: r21e
- uses: android-actions/setup-android@v2
# Runs a set of commands using the runners shell
name: 'Set up Android SDK'
- shell: bash
name: 'Set up Linux build environment'
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
run: |
......@@ -96,83 +120,115 @@ jobs:
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 Xvfb :0 -screen 0 1280x720x24 &
- run: |
# Test Linux native
- shell: bash
name: 'Compile and run Linux x64 tests'
run: |
export DISPLAY=:0
./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
./gradlew --no-daemon --stacktrace --info -Pskiko.native.enabled=true -Pkotlin.native.cacheKind.linuxX64=none -Pskiko.test.onci=true :skiko:awtTest
timeout-minutes: 25
- env:
- shell: bash
name: 'Publish to Maven Local, check AWT sample'
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
run: |
# Test 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
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
name: 'Save test results as artifact'
if: always()
with:
name: test-reports-linux
path: ./skiko/build/reports/tests
retention-days: 5
js:
runs-on: ubuntu-20.04
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '11'
# Runs a set of commands using the runners shell
- shell: bash
run: |
cd ./skiko
sudo apt-get update -y
sudo apt-get install binutils build-essential -y
sudo apt-get install software-properties-common -y
sudo apt-get install python git curl wget -y
if [ -d ./emsdk ]; then
cd ./emsdk
git pull
else
git clone https://github.com/emscripten-core/emsdk.git
cd ./emsdk
fi
./emsdk install 2.0.29
./emsdk activate 2.0.29
source ./emsdk_env.sh
cd ..
./gradlew --stacktrace --info -Pskiko.wasm.enabled=true -Pskiko.test.onci=true jsTest
./gradlew --stacktrace --info -Pskiko.wasm.enabled=true publishSkikoWasmRuntimePublicationToMavenLocal
- uses: actions/upload-artifact@v2
if: always()
with:
name: test-reports-js
path: ./skiko/build/reports/tests
retention-days: 5
windows:
js:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
name: 'Check out code'
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with:
distribution: 'adopt'
java-version: '11'
cache: 'gradle'
- shell: bash
name: 'Set up JS build environment'
run: |
cd ./skiko
sudo apt-get update -y
sudo apt-get install binutils build-essential -y
sudo apt-get install software-properties-common -y
sudo apt-get install python git curl wget -y
if [ -d ./emsdk ]; then
cd ./emsdk
git pull
else
git clone https://github.com/emscripten-core/emsdk.git
cd ./emsdk
fi
./emsdk install 2.0.29
./emsdk activate 2.0.29
- shell: bash
name: 'Compile and run JS tests'
run: |
source "$(pwd)/skiko/emsdk/emsdk_env.sh"
./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()
with:
name: test-reports-js
path: ./skiko/build/reports/tests
retention-days: 5
windows:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
name: 'Check out code'
- uses: microsoft/setup-msbuild@v1
- uses: ilammy/msvc-dev-cmd@v1
- uses: actions/setup-java@v2
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with:
distribution: 'adopt'
java-version: '11'
cache: 'gradle'
- 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: |
./gradlew --stacktrace --info -Pskiko.test.onci=true :skiko:awtTest
./gradlew --stacktrace --info :skiko:publishToMavenLocal
./gradlew --stacktrace --info :SkiaAwtSample:installDist # check jvm sample works
- uses: actions/upload-artifact@v2
./gradlew --stacktrace --info :SkiaAwtSample:installDist
- uses: actions/upload-artifact@v3
name: 'Save test results as artifact'
if: always()
with:
name: test-reports-windows
......
# Build Skiko documentation
name: Doc
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
# Temporary, for testing. Remove!
#pull_request:
# branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# See https://github.com/marketplace/actions/deploy-to-github-pages
jobs:
dokka:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
- uses: actions/checkout@v3
name: 'Check out code'
- uses: actions/setup-java@v3
name: 'Set up JDK 11'
with:
distribution: 'adopt'
java-version: '11'
- name: Build docs
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
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'
- name: 'Publish documentation'
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
BRANCH: gh-pages
FOLDER: ./skiko/build/dokka/html
\ No newline at end of file
FOLDER: ./skiko/build/dokka/html
......@@ -4,3 +4,6 @@ build
local.properties
.DS_Store
dependencies/
# Screenshot test actual files
**/src/**/screenshots/*_actual.png
......@@ -4,16 +4,20 @@
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<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">
<list />
</option>
<option name="taskNames">
<list />
<list>
<option value=":awtTest" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
\ No newline at end of file
......@@ -10,7 +10,7 @@
</option>
<option name="taskNames">
<list>
<option value="publishToMavenLocal" />
<option value=":publishToMavenLocal" />
</list>
</option>
<option name="vmOptions" value="" />
......
import de.undercouch.gradle.tasks.download.Download
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.crypto.checksum.Checksum
import org.gradle.api.tasks.testing.AbstractTestTask
import org.jetbrains.compose.internal.publishing.MavenCentralProperties
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
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.konan.target.KonanTarget
plugins {
kotlin("multiplatform") version "1.8.20"
......@@ -88,7 +86,7 @@ if (supportWasm) {
buildTargetArch.set(osArch.second)
buildVariant.set(buildType)
libFiles = project.fileTree(unpackedSkia) { include("**/*.a") }
libFiles = project.fileTree(unpackedSkia) { include("**/*.a") }
objectFiles = project.fileTree(compileWasm.map { it.outDir.get() }) {
include("**/*.o")
}
......@@ -154,7 +152,7 @@ fun compileNativeBridgesTask(os: OS, arch: Arch, isArm64Simulator: Boolean): Tas
buildTargetArch.set(arch)
buildVariant.set(buildType)
when (os) {
when (os) {
OS.IOS -> {
val sdkRoot = "/Applications/Xcode.app/Contents/Developer/Platforms"
val iphoneOsSdk = "$sdkRoot/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
......@@ -215,7 +213,7 @@ internal val Project.isInIdea: Boolean
}
val Project.supportNative: Boolean
get() = findProperty("skiko.native.enabled") == "true" || isInIdea
get() = findProperty("skiko.native.enabled") == "true" || isInIdea
val Project.supportWasm: Boolean
get() = findProperty("skiko.wasm.enabled") == "true" || isInIdea
......@@ -906,80 +904,81 @@ fun createLinkJvmBindings(
compileTask: TaskProvider<CompileSkikoCppTask>,
objcCompileTask: TaskProvider<CompileSkikoObjCTask>?
) = project.registerSkikoTask<LinkSkikoTask>("linkJvmBindings", targetOs, targetArch) {
val target = targetId(targetOs, targetArch)
val skiaBinSubdir = "out/${buildType.id}-$target"
val skiaBinDir = skiaJvmBindingsDir.get().absolutePath + "/" + skiaBinSubdir
val osFlags: Array<String>
val target = targetId(targetOs, targetArch)
val skiaBinSubdir = "out/${buildType.id}-$target"
val skiaBinDir = skiaJvmBindingsDir.get().absolutePath + "/" + skiaBinSubdir
val osFlags: Array<String>
libFiles = fileTree(skiaJvmBindingsDir.map { it.resolve(skiaBinSubdir)}) {
include(if (targetOs.isWindows) "*.lib" else "*.a")
}
libFiles = fileTree(skiaJvmBindingsDir.map { it.resolve(skiaBinSubdir) }) {
include(if (targetOs.isWindows) "*.lib" else "*.a")
}
dependsOn(compileTask)
objectFiles = fileTree(compileTask.map { it.outDir.get() }) {
include("**/*.o")
}
val libNamePrefix = if (targetOs.isWindows) "skiko" else "libskiko"
libOutputFileName.set("$libNamePrefix-${targetOs.id}-${targetArch.id}${targetOs.dynamicLibExt}")
buildTargetOS.set(targetOs)
buildSuffix.set("jvm")
buildTargetArch.set(targetArch)
buildVariant.set(buildType)
linker.set(linkerForTarget(targetOs, targetArch))
dependsOn(compileTask)
objectFiles = fileTree(compileTask.map { it.outDir.get() }) {
include("**/*.o")
}
val libNamePrefix = if (targetOs.isWindows) "skiko" else "libskiko"
libOutputFileName.set("$libNamePrefix-${targetOs.id}-${targetArch.id}${targetOs.dynamicLibExt}")
buildTargetOS.set(targetOs)
buildSuffix.set("jvm")
buildTargetArch.set(targetArch)
buildVariant.set(buildType)
linker.set(linkerForTarget(targetOs, targetArch))
when (targetOs) {
OS.MacOS -> {
dependsOn(objcCompileTask!!)
objectFiles += fileTree(objcCompileTask.map { it.outDir.get() }) {
include("**/*.o")
}
osFlags = arrayOf(
*targetOs.clangFlags,
"-arch", if (targetArch == Arch.Arm64) "arm64" else "x86_64",
"-shared",
"-dead_strip",
"-lobjc",
"-install_name", "./${libOutputFileName.get()}",
"-current_version", skiko.planeDeployVersion,
"-framework", "AppKit",
"-framework", "CoreFoundation",
"-framework", "CoreGraphics",
"-framework", "CoreServices",
"-framework", "CoreText",
"-framework", "Foundation",
"-framework", "IOKit",
"-framework", "Metal",
"-framework", "OpenGL",
"-framework", "QuartzCore" // for CoreAnimation
)
}
OS.Linux -> {
osFlags = arrayOf(
"-shared",
"-static-libstdc++",
"-static-libgcc",
"-lGL",
"-lX11",
"-lfontconfig",
// A fix for https://github.com/JetBrains/compose-jb/issues/413.
// Dynamic position independent linking uses PLT thunks relying on jump targets in GOT (Global Offsets Table).
// GOT entries marked as (for example) R_X86_64_JUMP_SLOT in the relocation table. So, if there's code loading
// platform libstdc++.so, lazy resolve code will resolve GOT entries to platform libstdc++.so on first invocation,
// and so further execution will break, as those two libstdc++ are not compatible.
// To fix it we enforce resolve of all GOT entries at library load time, and make it read-only afterwards.
"-Wl,-z,relro,-z,now",
// Hack to fix problem with linker not always finding certain declarations.
"$skiaBinDir/libsksg.a",
"$skiaBinDir/libskia.a",
"$skiaBinDir/libskunicode.a"
)
when (targetOs) {
OS.MacOS -> {
dependsOn(objcCompileTask!!)
objectFiles += fileTree(objcCompileTask.map { it.outDir.get() }) {
include("**/*.o")
}
OS.Windows -> {
linker.set(windowsSdkPaths.linker.absolutePath)
libDirs.set(windowsSdkPaths.libDirs)
osFlags = mutableListOf<String>().apply {
addAll(buildType.msvcLinkerFlags)
addAll(arrayOf(
osFlags = arrayOf(
*targetOs.clangFlags,
"-arch", if (targetArch == Arch.Arm64) "arm64" else "x86_64",
"-shared",
"-dead_strip",
"-lobjc",
"-install_name", "./${libOutputFileName.get()}",
"-current_version", skiko.planeDeployVersion,
"-framework", "AppKit",
"-framework", "CoreFoundation",
"-framework", "CoreGraphics",
"-framework", "CoreServices",
"-framework", "CoreText",
"-framework", "Foundation",
"-framework", "IOKit",
"-framework", "Metal",
"-framework", "OpenGL",
"-framework", "QuartzCore" // for CoreAnimation
)
}
OS.Linux -> {
osFlags = arrayOf(
"-shared",
"-static-libstdc++",
"-static-libgcc",
"-lGL",
"-lX11",
"-lfontconfig",
// A fix for https://github.com/JetBrains/compose-jb/issues/413.
// Dynamic position independent linking uses PLT thunks relying on jump targets in GOT (Global Offsets Table).
// GOT entries marked as (for example) R_X86_64_JUMP_SLOT in the relocation table. So, if there's code loading
// platform libstdc++.so, lazy resolve code will resolve GOT entries to platform libstdc++.so on first invocation,
// and so further execution will break, as those two libstdc++ are not compatible.
// To fix it we enforce resolve of all GOT entries at library load time, and make it read-only afterwards.
"-Wl,-z,relro,-z,now",
// Hack to fix problem with linker not always finding certain declarations.
"$skiaBinDir/libsksg.a",
"$skiaBinDir/libskia.a",
"$skiaBinDir/libskunicode.a"
)
}
OS.Windows -> {
linker.set(windowsSdkPaths.linker.absolutePath)
libDirs.set(windowsSdkPaths.libDirs)
osFlags = mutableListOf<String>().apply {
addAll(buildType.msvcLinkerFlags)
addAll(
arrayOf(
"/NOLOGO",
"/DLL",
"Advapi32.lib",
......@@ -988,29 +987,30 @@ fun createLinkJvmBindings(
"opengl32.lib",
"shcore.lib",
"user32.lib",
))
if (buildType == SkiaBuildType.DEBUG) add("dxgi.lib")
}.toTypedArray()
}
OS.Android -> {
osFlags = arrayOf(
"-shared",
"-static-libstdc++",
"-lGLESv3",
"-lEGL",
"-llog",
"-landroid",
// Hack to fix problem with linker not always finding certain declarations.
"$skiaBinDir/libskia.a",
)
)
linker.set(androidClangFor(targetArch))
}
OS.Wasm, OS.IOS -> {
throw GradleException("This task shalln't be used with $targetOs")
}
if (buildType == SkiaBuildType.DEBUG) add("dxgi.lib")
}.toTypedArray()
}
OS.Android -> {
osFlags = arrayOf(
"-shared",
"-static-libstdc++",
"-lGLESv3",
"-lEGL",
"-llog",
"-landroid",
// Hack to fix problem with linker not always finding certain declarations.
"$skiaBinDir/libskia.a",
)
linker.set(androidClangFor(targetArch))
}
OS.Wasm, OS.IOS -> {
throw GradleException("This task shalln't be used with $targetOs")
}
flags.set(listOf(*osFlags))
}
flags.set(listOf(*osFlags))
}
fun KotlinTarget.generateVersion(
targetOs: OS,
......@@ -1034,11 +1034,12 @@ fun KotlinTarget.generateVersion(
val target = "${targetOs.id}-${targetArch.id}"
val skiaTag = project.property("dependencies.skia.$target") as String
File(out).writeText("""
File(out).writeText(
"""
package org.jetbrains.skiko
object Version {
val skiko = "${skiko.deployVersion}"
val skia = "${skiaTag}"
val skia = "$skiaTag"
}
""".trimIndent()
)
......@@ -1105,7 +1106,7 @@ fun skikoJvmRuntimeJarTask(
dependsOn(awtJar)
val target = targetId(targetOs, targetArch)
archiveBaseName.set("skiko-$target")
nativeFiles.forEach { provider -> from(provider) }
nativeFiles.forEach { provider -> from(provider) }
}
fun skikoRuntimeDirForTestsTask(
......@@ -1135,7 +1136,7 @@ tasks.withType<Test>().configureEach {
options {
val dir = skikoRuntimeDirForTests.map { it.destinationDir }.get()
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.test.screenshots.dir", File(project.projectDir, "src/jvmTest/screenshots").absolutePath)
......@@ -1144,7 +1145,10 @@ tasks.withType<Test>().configureEach {
val testingOnCI = System.getProperty("skiko.test.onci", "false").toBoolean()
val canRunPerformanceTests = testingOnCI
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.renderApi", System.getProperty("skiko.test.ui.renderApi", "all"))
......
......@@ -27,4 +27,4 @@ RUN $SDK_MANAGER "ndk;$NDK_VERSION" && \
cd $ANDROID_SDK_ROOT/ndk/$NDK_VERSION && \
ls -1 | grep -v toolchains | xargs rm -rf
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
\ No newline at end of file
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
......@@ -18,4 +18,4 @@ RUN git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git'
# Use UTF-8 by default
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
\ No newline at end of file
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
......@@ -13,8 +13,8 @@ import javax.swing.UIManager
actual fun setSystemLookAndFeel() = UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())
internal actual fun makeDefaultRenderFactory(): RenderFactory {
return object : RenderFactory {
internal actual fun makeDefaultRenderFactory(): RenderFactory =
object : RenderFactory {
override fun createRedrawer(
layer: SkiaLayer,
renderApi: GraphicsApi,
......@@ -36,10 +36,9 @@ internal actual fun makeDefaultRenderFactory(): RenderFactory {
GraphicsApi.SOFTWARE_FAST -> LinuxSoftwareRedrawer(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) {
Desktop.getDesktop().browse(URI(uri))
......@@ -56,6 +55,7 @@ private val systemClipboard by lazy {
internal actual fun ClipboardManager_setText(text: String) {
systemClipboard?.setContents(StringSelection(text), null)
}
internal actual fun ClipboardManager_getText(): String? {
return try {
systemClipboard?.getData(DataFlavor.stringFlavor) as String?
......@@ -92,4 +92,4 @@ internal actual fun getCursorById(id: PredefinedCursorsId): Cursor =
PredefinedCursorsId.CROSSHAIR -> Cursor(Cursor.CROSSHAIR_CURSOR)
PredefinedCursorsId.HAND -> Cursor(Cursor.HAND_CURSOR)
PredefinedCursorsId.TEXT -> Cursor(Cursor.TEXT_CURSOR)
}
\ No newline at end of file
}
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.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 {
companion object {
......@@ -27,8 +20,8 @@ open class FontMgr : RefCnt {
reachabilityBarrier(this)
}
fun getFamilyName(index: Int): String {
return try {
fun getFamilyName(index: Int): String =
try {
Stats.onNativeCall()
withStringResult {
_nGetFamilyName(_ptr, index)
......@@ -36,59 +29,55 @@ open class FontMgr : RefCnt {
} finally {
reachabilityBarrier(this)
}
}
fun makeStyleSet(index: Int): FontStyleSet? {
return try {
fun makeStyleSet(index: Int): FontStyleSet? =
try {
Stats.onNativeCall()
val ptr = _nMakeStyleSet(_ptr, index)
if (ptr == NullPointer) null else FontStyleSet(ptr)
} finally {
reachabilityBarrier(this)
}
}
/**
* The caller must call [.close] on the returned object.
* Never returns null; will return an empty set if the name is not found.
* The caller must call [close] on the returned object.
* 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.
* Note that most systems don't have a default system family, so passing null will often
* result in the empty set.
* 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 result in the empty set.
*
* 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 {
return try {
fun matchFamily(familyName: String?): FontStyleSet =
try {
Stats.onNativeCall()
interopScope { FontStyleSet(_nMatchFamily(_ptr, toInterop(familyName))) }
interopScope { FontStyleSet(_nMatchFamily(_ptr, toInterop(familyName))) }
} finally {
reachabilityBarrier(this)
}
}
/**
* 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
* object. Will return null if no 'good' match is found.
* Find the closest matching typeface to the specified [familyName] and [style]
* and return it. The caller must call [close] on the returned
* 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.
*
* 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.
*/
fun matchFamilyStyle(familyName: String?, style: FontStyle): Typeface? {
return try {
fun matchFamilyStyle(familyName: String?, style: FontStyle): Typeface? =
try {
Stats.onNativeCall()
val ptr = interopScope { _nMatchFamilyStyle(_ptr, toInterop(familyName), style._value) }
if (ptr == NullPointer) null else Typeface(ptr)
} finally {
reachabilityBarrier(this)
}
}
fun matchFamiliesStyle(families: Array<String?>, style: FontStyle): Typeface? {
for (family in families) {
......@@ -103,13 +92,13 @@ open class FontMgr : RefCnt {
* 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.
*
* 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.
*
* Passing `null` as the parameter for `familyName` will return the
* Passing `null` as the value for [familyName] will return the
* 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
* requested character will be matched.
*/
......@@ -118,8 +107,8 @@ open class FontMgr : RefCnt {
style: FontStyle,
bcp47: Array<String>?,
character: Int
): Typeface? {
return try {
): Typeface? =
try {
Stats.onNativeCall()
val ptr = interopScope {
_nMatchFamilyStyleCharacter(
......@@ -135,7 +124,6 @@ open class FontMgr : RefCnt {
} finally {
reachabilityBarrier(this)
}
}
fun matchFamiliesStyleCharacter(
families: Array<String?>,
......@@ -152,11 +140,11 @@ open class FontMgr : RefCnt {
/**
* 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.
*/
fun makeFromData(data: Data?, ttcIndex: Int = 0): Typeface? {
return try {
fun makeFromData(data: Data?, ttcIndex: Int = 0): Typeface? =
try {
Stats.onNativeCall()
val ptr =
_nMakeFromData(_ptr, getPtr(data), ttcIndex)
......@@ -165,7 +153,6 @@ open class FontMgr : RefCnt {
reachabilityBarrier(this)
reachabilityBarrier(data)
}
}
internal constructor(ptr: NativePointer) : super(ptr)
......
......@@ -32,9 +32,7 @@ class FontStyle {
return FontStyle(weight, width, slant)
}
override fun toString(): String {
return "FontStyle(weight=$weight, width=$width, slant=$slant)"
}
override fun toString(): String = "FontStyle(weight=$weight, width=$width, slant=$slant)"
override fun equals(other: Any?): Boolean {
if (other === this) return true
......@@ -55,4 +53,4 @@ class FontStyle {
val ITALIC = FontStyle(FontWeight.NORMAL, FontWidth.NORMAL, FontSlant.ITALIC)
val BOLD_ITALIC = FontStyle(FontWeight.BOLD, FontWidth.NORMAL, FontSlant.ITALIC)
}
}
\ No newline at end of file
}
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.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) {
companion object {
......@@ -401,6 +391,8 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
} finally {
reachabilityBarrier(this)
}
override fun toString() = "Typeface(familyName='$familyName', fontStyle=$fontStyle, uniqueId=$uniqueId)"
}
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetUniqueId")
......@@ -494,4 +486,4 @@ private external fun _nGetKerningPairAdjustments(
private external fun _nGetFamilyNames(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetFamilyName")
private external fun _nGetFamilyName(ptr: NativePointer): NativePointer
\ No newline at end of file
private external fun _nGetFamilyName(ptr: NativePointer): NativePointer
......@@ -6,8 +6,8 @@ import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
/**
* Behaves as Channel<Unit>(Channel.RENDEZVOUS), but with ability to send value to all current consumers
* (which await on `receive` method).
* Behaves as `Channel<Unit>(Channel.RENDEZVOUS)`, but with ability to send a value to all current consumers
* (which will await on `receive` method).
*/
internal class RendezvousBroadcastChannel<T> {
private val onRequest = Channel<Unit>(Channel.CONFLATED)
......@@ -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.
*/
......@@ -42,4 +42,4 @@ internal class RendezvousBroadcastChannel<T> {
}
onRequest.trySend(Unit)
}
}
\ No newline at end of file
}
......@@ -49,4 +49,4 @@ class CodecTest {
assertEquals(200, frameInfo.duration)
}
}
}
\ No newline at end of file
}
......@@ -104,4 +104,4 @@ class FontMgrTest {
}
}
}
}
\ No newline at end of file
}
......@@ -4,10 +4,8 @@ import org.jetbrains.skia.impl.use
import org.jetbrains.skia.tests.assertCloseEnough
import org.jetbrains.skia.tests.assertContentCloseEnough
import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skiko.KotlinBackend
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.hostOs
import org.jetbrains.skiko.kotlinBackend
import org.jetbrains.skiko.tests.runTest
import kotlin.test.Test
import kotlin.test.assertContentEquals
......@@ -137,4 +135,4 @@ class FontTests {
}
}
}
\ No newline at end of file
}
......@@ -139,4 +139,4 @@ class ParagraphTest {
}
}
}
}
\ No newline at end of file
}
......@@ -20,4 +20,4 @@ class PixmapTest {
assertFalse(pixmap.computeIsOpaque())
}
}
\ No newline at end of file
}
......@@ -3,12 +3,12 @@ package org.jetbrains.skia
import org.jetbrains.skia.tests.assertCloseEnough
import org.jetbrains.skia.tests.assertContentCloseEnough
import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skiko.KotlinBackend
import org.jetbrains.skiko.kotlinBackend
import org.jetbrains.skiko.tests.runTest
import kotlin.math.cos
import kotlin.math.sin
import kotlin.test.*
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals
class TextBlobBuilderTest {
......
......@@ -92,4 +92,4 @@ class FontCollectionTest {
}
}
\ No newline at end of file
}
......@@ -3,8 +3,6 @@ package org.jetbrains.skiko
import org.jetbrains.skia.*
import org.jetbrains.skia.tests.assertCloseEnough
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 kotlin.test.*
......@@ -93,4 +91,4 @@ class TypefaceTest {
assertEquals("Inter", interV.familyName)
}
}
\ No newline at end of file
}
......@@ -12,8 +12,8 @@ object Library {
private val skikoLibraryPath = System.getProperty(SKIKO_LIBRARY_PATH_PROPERTY)
private var copyDir: File? = null
// Same 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.
// A native library cannot be loaded in several classloaders, so we have to clone
// the native library to allow Skiko loading to work properly in complex cases, i.e.,
// several IDEA plugins.
private fun loadLibraryOrCopy(library: File) {
try {
......@@ -49,8 +49,8 @@ object Library {
// This function does the following: on request to load given resource,
// 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
// localization resource on platforms where it is needed.
// in Skiko's home, and if not - unpacks it. It could also load additional
// localization resources, on platforms where it is needed.
@Synchronized
fun load() {
if (!loaded.compareAndSet(false, true)) return
......
......@@ -32,7 +32,7 @@ internal object Setup {
}
if (automateGC) {
FrameWatcher.start()
FrameWatcher.start()
}
}
}
......
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