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 - 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: | 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
path: ./skiko/build/reports/tests path: ./skiko/build/reports/tests
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
./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:iosSimulatorArm64Test # iosSimulatorArm64Test will build the binary but the tests will be skipped due to X64 host machine
./gradlew --stacktrace --info -Pskiko.native.enabled=true :skiko:publishToMavenLocal - shell: bash
# TODO run iOS specific tests on iPhone simulator name: 'Compile iOS arm64 tests'
- uses: actions/upload-artifact@v2 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() if: always()
with: with:
name: test-reports-macos name: test-reports-macos
path: ./skiko/build/reports/tests path: ./skiko/build/reports/tests
retention-days: 5 retention-days: 5
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,83 +120,115 @@ jobs: ...@@ -96,83 +120,115 @@ 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
path: ./skiko/build/reports/tests path: ./skiko/build/reports/tests
retention-days: 5 retention-days: 5
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: - uses: actions/checkout@v3
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it name: 'Check out code'
- uses: actions/checkout@v2
- uses: actions/setup-java@v2 - uses: actions/setup-java@v3
with: name: 'Set up JDK 11'
distribution: 'adopt' with:
java-version: '11' distribution: 'adopt'
# Runs a set of commands using the runners shell java-version: '11'
- shell: bash cache: 'gradle'
run: |
cd ./skiko - shell: bash
sudo apt-get update -y name: 'Set up JS build environment'
sudo apt-get install binutils build-essential -y run: |
sudo apt-get install software-properties-common -y cd ./skiko
sudo apt-get install python git curl wget -y sudo apt-get update -y
if [ -d ./emsdk ]; then sudo apt-get install binutils build-essential -y
cd ./emsdk sudo apt-get install software-properties-common -y
git pull sudo apt-get install python git curl wget -y
else if [ -d ./emsdk ]; then
git clone https://github.com/emscripten-core/emsdk.git cd ./emsdk
cd ./emsdk git pull
fi else
./emsdk install 2.0.29 git clone https://github.com/emscripten-core/emsdk.git
./emsdk activate 2.0.29 cd ./emsdk
source ./emsdk_env.sh fi
cd .. ./emsdk install 2.0.29
./gradlew --stacktrace --info -Pskiko.wasm.enabled=true -Pskiko.test.onci=true jsTest ./emsdk activate 2.0.29
./gradlew --stacktrace --info -Pskiko.wasm.enabled=true publishSkikoWasmRuntimePublicationToMavenLocal - shell: bash
- uses: actions/upload-artifact@v2 name: 'Compile and run JS tests'
if: always() run: |
with: source "$(pwd)/skiko/emsdk/emsdk_env.sh"
name: test-reports-js ./gradlew --stacktrace --info -Pskiko.wasm.enabled=true -Pskiko.test.onci=true :skiko:jsTest
path: ./skiko/build/reports/tests - shell: bash
retention-days: 5 name: 'Publish WASM runtime to Maven Local'
run: |
windows: 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 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'
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: '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 uses: JamesIves/github-pages-deploy-action@releases/v3
with: with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
BRANCH: gh-pages BRANCH: gh-pages
FOLDER: ./skiko/build/dokka/html FOLDER: ./skiko/build/dokka/html
\ No newline at end of file
...@@ -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"
...@@ -88,7 +86,7 @@ if (supportWasm) { ...@@ -88,7 +86,7 @@ if (supportWasm) {
buildTargetArch.set(osArch.second) buildTargetArch.set(osArch.second)
buildVariant.set(buildType) buildVariant.set(buildType)
libFiles = project.fileTree(unpackedSkia) { include("**/*.a") } libFiles = project.fileTree(unpackedSkia) { include("**/*.a") }
objectFiles = project.fileTree(compileWasm.map { it.outDir.get() }) { objectFiles = project.fileTree(compileWasm.map { it.outDir.get() }) {
include("**/*.o") include("**/*.o")
} }
...@@ -154,7 +152,7 @@ fun compileNativeBridgesTask(os: OS, arch: Arch, isArm64Simulator: Boolean): Tas ...@@ -154,7 +152,7 @@ fun compileNativeBridgesTask(os: OS, arch: Arch, isArm64Simulator: Boolean): Tas
buildTargetArch.set(arch) buildTargetArch.set(arch)
buildVariant.set(buildType) buildVariant.set(buildType)
when (os) { when (os) {
OS.IOS -> { OS.IOS -> {
val sdkRoot = "/Applications/Xcode.app/Contents/Developer/Platforms" val sdkRoot = "/Applications/Xcode.app/Contents/Developer/Platforms"
val iphoneOsSdk = "$sdkRoot/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" val iphoneOsSdk = "$sdkRoot/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
...@@ -215,7 +213,7 @@ internal val Project.isInIdea: Boolean ...@@ -215,7 +213,7 @@ internal val Project.isInIdea: Boolean
} }
val Project.supportNative: Boolean val Project.supportNative: Boolean
get() = findProperty("skiko.native.enabled") == "true" || isInIdea get() = findProperty("skiko.native.enabled") == "true" || isInIdea
val Project.supportWasm: Boolean val Project.supportWasm: Boolean
get() = findProperty("skiko.wasm.enabled") == "true" || isInIdea get() = findProperty("skiko.wasm.enabled") == "true" || isInIdea
...@@ -906,80 +904,81 @@ fun createLinkJvmBindings( ...@@ -906,80 +904,81 @@ fun createLinkJvmBindings(
compileTask: TaskProvider<CompileSkikoCppTask>, compileTask: TaskProvider<CompileSkikoCppTask>,
objcCompileTask: TaskProvider<CompileSkikoObjCTask>? objcCompileTask: TaskProvider<CompileSkikoObjCTask>?
) = project.registerSkikoTask<LinkSkikoTask>("linkJvmBindings", targetOs, targetArch) { ) = project.registerSkikoTask<LinkSkikoTask>("linkJvmBindings", targetOs, targetArch) {
val target = targetId(targetOs, targetArch) val target = targetId(targetOs, targetArch)
val skiaBinSubdir = "out/${buildType.id}-$target" val skiaBinSubdir = "out/${buildType.id}-$target"
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")
} }
dependsOn(compileTask) dependsOn(compileTask)
objectFiles = fileTree(compileTask.map { it.outDir.get() }) { objectFiles = fileTree(compileTask.map { it.outDir.get() }) {
include("**/*.o") include("**/*.o")
} }
val libNamePrefix = if (targetOs.isWindows) "skiko" else "libskiko" val libNamePrefix = if (targetOs.isWindows) "skiko" else "libskiko"
libOutputFileName.set("$libNamePrefix-${targetOs.id}-${targetArch.id}${targetOs.dynamicLibExt}") libOutputFileName.set("$libNamePrefix-${targetOs.id}-${targetArch.id}${targetOs.dynamicLibExt}")
buildTargetOS.set(targetOs) buildTargetOS.set(targetOs)
buildSuffix.set("jvm") buildSuffix.set("jvm")
buildTargetArch.set(targetArch) buildTargetArch.set(targetArch)
buildVariant.set(buildType) buildVariant.set(buildType)
linker.set(linkerForTarget(targetOs, targetArch)) linker.set(linkerForTarget(targetOs, targetArch))
when (targetOs) { when (targetOs) {
OS.MacOS -> { OS.MacOS -> {
dependsOn(objcCompileTask!!) dependsOn(objcCompileTask!!)
objectFiles += fileTree(objcCompileTask.map { it.outDir.get() }) { objectFiles += fileTree(objcCompileTask.map { it.outDir.get() }) {
include("**/*.o") 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"
)
} }
OS.Windows -> { osFlags = arrayOf(
linker.set(windowsSdkPaths.linker.absolutePath) *targetOs.clangFlags,
libDirs.set(windowsSdkPaths.libDirs) "-arch", if (targetArch == Arch.Arm64) "arm64" else "x86_64",
osFlags = mutableListOf<String>().apply { "-shared",
addAll(buildType.msvcLinkerFlags) "-dead_strip",
addAll(arrayOf( "-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", "/NOLOGO",
"/DLL", "/DLL",
"Advapi32.lib", "Advapi32.lib",
...@@ -988,29 +987,30 @@ fun createLinkJvmBindings( ...@@ -988,29 +987,30 @@ fun createLinkJvmBindings(
"opengl32.lib", "opengl32.lib",
"shcore.lib", "shcore.lib",
"user32.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)) if (buildType == SkiaBuildType.DEBUG) add("dxgi.lib")
} }.toTypedArray()
OS.Wasm, OS.IOS -> { }
throw GradleException("This task shalln't be used with $targetOs") 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( 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()
) )
...@@ -1105,7 +1106,7 @@ fun skikoJvmRuntimeJarTask( ...@@ -1105,7 +1106,7 @@ fun skikoJvmRuntimeJarTask(
dependsOn(awtJar) dependsOn(awtJar)
val target = targetId(targetOs, targetArch) val target = targetId(targetOs, targetArch)
archiveBaseName.set("skiko-$target") archiveBaseName.set("skiko-$target")
nativeFiles.forEach { provider -> from(provider) } nativeFiles.forEach { provider -> from(provider) }
} }
fun skikoRuntimeDirForTestsTask( fun skikoRuntimeDirForTestsTask(
...@@ -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"))
......
...@@ -27,4 +27,4 @@ RUN $SDK_MANAGER "ndk;$NDK_VERSION" && \ ...@@ -27,4 +27,4 @@ RUN $SDK_MANAGER "ndk;$NDK_VERSION" && \
cd $ANDROID_SDK_ROOT/ndk/$NDK_VERSION && \ cd $ANDROID_SDK_ROOT/ndk/$NDK_VERSION && \
ls -1 | grep -v toolchains | xargs rm -rf 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 LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
\ No newline at end of file
...@@ -18,4 +18,4 @@ RUN git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git' ...@@ -18,4 +18,4 @@ RUN git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git'
# Use UTF-8 by default # Use UTF-8 by default
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
\ No newline at end of file
...@@ -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?
...@@ -92,4 +92,4 @@ internal actual fun getCursorById(id: PredefinedCursorsId): Cursor = ...@@ -92,4 +92,4 @@ internal actual fun getCursorById(id: PredefinedCursorsId): Cursor =
PredefinedCursorsId.CROSSHAIR -> Cursor(Cursor.CROSSHAIR_CURSOR) PredefinedCursorsId.CROSSHAIR -> Cursor(Cursor.CROSSHAIR_CURSOR)
PredefinedCursorsId.HAND -> Cursor(Cursor.HAND_CURSOR) PredefinedCursorsId.HAND -> Cursor(Cursor.HAND_CURSOR)
PredefinedCursorsId.TEXT -> Cursor(Cursor.TEXT_CURSOR) PredefinedCursorsId.TEXT -> Cursor(Cursor.TEXT_CURSOR)
} }
\ No newline at end of file
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
...@@ -55,4 +53,4 @@ class FontStyle { ...@@ -55,4 +53,4 @@ class FontStyle {
val ITALIC = FontStyle(FontWeight.NORMAL, FontWidth.NORMAL, FontSlant.ITALIC) val ITALIC = FontStyle(FontWeight.NORMAL, FontWidth.NORMAL, FontSlant.ITALIC)
val BOLD_ITALIC = FontStyle(FontWeight.BOLD, FontWidth.NORMAL, FontSlant.ITALIC) val BOLD_ITALIC = FontStyle(FontWeight.BOLD, FontWidth.NORMAL, FontSlant.ITALIC)
} }
} }
\ No newline at end of file
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")
...@@ -494,4 +486,4 @@ private external fun _nGetKerningPairAdjustments( ...@@ -494,4 +486,4 @@ private external fun _nGetKerningPairAdjustments(
private external fun _nGetFamilyNames(ptr: NativePointer): NativePointer private external fun _nGetFamilyNames(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetFamilyName") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetFamilyName")
private external fun _nGetFamilyName(ptr: NativePointer): NativePointer private external fun _nGetFamilyName(ptr: NativePointer): NativePointer
\ No newline at end of file
...@@ -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.
*/ */
...@@ -42,4 +42,4 @@ internal class RendezvousBroadcastChannel<T> { ...@@ -42,4 +42,4 @@ internal class RendezvousBroadcastChannel<T> {
} }
onRequest.trySend(Unit) onRequest.trySend(Unit)
} }
} }
\ No newline at end of file
...@@ -49,4 +49,4 @@ class CodecTest { ...@@ -49,4 +49,4 @@ class CodecTest {
assertEquals(200, frameInfo.duration) assertEquals(200, frameInfo.duration)
} }
} }
} }
\ No newline at end of file
...@@ -104,4 +104,4 @@ class FontMgrTest { ...@@ -104,4 +104,4 @@ class FontMgrTest {
} }
} }
} }
} }
\ No newline at end of file
...@@ -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
...@@ -137,4 +135,4 @@ class FontTests { ...@@ -137,4 +135,4 @@ class FontTests {
} }
} }
} }
\ No newline at end of file
...@@ -139,4 +139,4 @@ class ParagraphTest { ...@@ -139,4 +139,4 @@ class ParagraphTest {
} }
} }
} }
} }
\ No newline at end of file
...@@ -20,4 +20,4 @@ class PixmapTest { ...@@ -20,4 +20,4 @@ class PixmapTest {
assertFalse(pixmap.computeIsOpaque()) assertFalse(pixmap.computeIsOpaque())
} }
} }
\ No newline at end of file
...@@ -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 {
......
...@@ -92,4 +92,4 @@ class FontCollectionTest { ...@@ -92,4 +92,4 @@ class FontCollectionTest {
} }
} }
\ No newline at end of file
...@@ -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.*
...@@ -93,4 +91,4 @@ class TypefaceTest { ...@@ -93,4 +91,4 @@ class TypefaceTest {
assertEquals("Inter", interV.familyName) assertEquals("Inter", interV.familyName)
} }
} }
\ No newline at end of file
...@@ -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
......
...@@ -32,7 +32,7 @@ internal object Setup { ...@@ -32,7 +32,7 @@ internal object Setup {
} }
if (automateGC) { 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