From ff91c521f7b1dc484a61c37d6e49a98f5d9129e1 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sat, 14 Oct 2023 16:20:34 +0200 Subject: [PATCH 1/5] Versioning and docs --- .github/workflows/build.yml | 4 +- .gitignore | 5 +- .nuke/build.schema.json | 12 ++ LICENSE | 102 +++++++++++ README.md | 8 +- build/Build.DotNet.cs | 42 ++++- build/Build.Java.cs | 41 +++++ build/Build.LibAlphaSkia.cs | 92 +++++++++- build/Build.Native.cs | 26 ++- build/Build.Node.cs | 99 +++++++++-- build/Build.cs | 23 ++- .../AlphaSkia.Native.Android.csproj | 4 +- lib/dotnet/AlphaSkia.Native.Android/README.md | 4 +- .../AlphaSkia.Native.Linux.csproj | 4 +- lib/dotnet/AlphaSkia.Native.Linux/README.md | 4 +- .../AlphaSkia.Native.MacOs.csproj | 4 +- lib/dotnet/AlphaSkia.Native.MacOs/README.md | 4 +- .../AlphaSkia.Native.Windows.csproj | 4 +- lib/dotnet/AlphaSkia.Native.Windows/README.md | 4 +- .../AlphaSkia.Native.iOS.csproj | 4 +- lib/dotnet/AlphaSkia.Native.iOS/README.md | 4 +- lib/dotnet/AlphaSkia/AlphaSkia.csproj | 2 + lib/dotnet/AlphaSkia/AlphaSkiaCanvas.cs | 4 +- lib/dotnet/AlphaSkia/AlphaSkiaNative.cs | 20 ++- lib/dotnet/AlphaSkia/AlphaSkiaPlatform.cs | 2 +- lib/dotnet/AlphaSkia/AlphaSkiaTypeface.cs | 15 +- lib/dotnet/AlphaSkia/README.md | 4 +- lib/dotnet/Directory.Build.props | 10 ++ .../inspectionProfiles/Project_Default.xml | 17 ++ lib/java/android/build.gradle.kts | 4 + .../alphatab/alphaskia/AlphaSkiaAndroid.java | 10 +- lib/java/build.gradle.kts | 140 ++++++++++++++- lib/java/linux/build.gradle.kts | 4 + .../alphatab/alphaskia/AlphaSkiaLinux.java | 6 + lib/java/macos/build.gradle.kts | 4 + .../alphatab/alphaskia/AlphaSkiaMacOs.java | 12 +- lib/java/main/build.gradle.kts | 10 +- .../alphatab/alphaskia/AlphaSkiaCanvas.java | 25 ++- .../alphaskia/AlphaSkiaColorType.java | 2 +- .../alphatab/alphaskia/AlphaSkiaNative.java | 4 +- .../alphatab/alphaskia/AlphaSkiaPlatform.java | 28 ++- .../alphaskia/AlphaSkiaTextBaseline.java | 1 - .../alphatab/alphaskia/AlphaSkiaTypeface.java | 15 ++ lib/java/windows/build.gradle.kts | 5 + .../alphatab/alphaskia/AlphaSkiaWindows.java | 10 +- lib/node/alphaskia-linux/package.json | 9 +- lib/node/alphaskia-macos/package.json | 9 +- lib/node/alphaskia-windows/package.json | 9 +- lib/node/alphaskia/package.json | 9 +- lib/node/alphaskia/rollup.config.js | 3 +- lib/node/alphaskia/src/AlphaSkiaCanvas.ts | 161 +++++++++++++++++- lib/node/alphaskia/src/AlphaSkiaData.ts | 6 +- lib/node/alphaskia/src/AlphaSkiaImage.ts | 23 +++ lib/node/alphaskia/src/AlphaSkiaNative.ts | 7 + lib/node/alphaskia/src/AlphaSkiaPlatform.ts | 14 ++ lib/node/alphaskia/src/AlphaSkiaTypeface.ts | 22 ++- lib/node/alphaskia/src/addon.ts | 36 +++- wrapper/src/alphaskia.rc | 57 +++++++ 58 files changed, 1107 insertions(+), 106 deletions(-) create mode 100644 LICENSE create mode 100644 lib/java/.idea/inspectionProfiles/Project_Default.xml create mode 100644 wrapper/src/alphaskia.rc diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index afbb4b2..c97bc4d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -216,9 +216,9 @@ jobs: - run: ./build.cmd Java - uses: actions/upload-artifact@v3 with: - name: Jars + name: Maven path: | - lib/java/*/build/libs/*.jar + lib/dist/**/*.* node: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 6fd884f..2cb66b3 100644 --- a/.gitignore +++ b/.gitignore @@ -713,6 +713,9 @@ fabric.properties !/build !/lib +/wrapper/include/generated /lib/java/**/test-outputs +/lib/java/local.properties /lib/node/**/test-outputs -/lib/node/*.tgz \ No newline at end of file +/lib/node/*/*.tgz +/lib/dotnet/Version.props \ No newline at end of file diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index 050d30e..c6ea6dc 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -28,6 +28,9 @@ "GnExe": { "type": "string" }, + "GnVerbose": { + "type": "boolean" + }, "GradlewExe": { "type": "string" }, @@ -56,6 +59,9 @@ "VSCode" ] }, + "IsReleaseBuild": { + "type": "boolean" + }, "JavaHome": { "type": "string" }, @@ -68,6 +74,9 @@ "NinjaExe": { "type": "string" }, + "NinjaVerbose": { + "type": "boolean" + }, "NoLogo": { "type": "boolean", "description": "Disables displaying the NUKE logo" @@ -93,6 +102,9 @@ "PythonExe": { "type": "string" }, + "Rebuild": { + "type": "boolean" + }, "Root": { "type": "string", "description": "Root directory during build execution" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d03885e --- /dev/null +++ b/LICENSE @@ -0,0 +1,102 @@ +BSD 3-Clause License + +Copyright (c) 2023, Daniel Kuschny + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +# Skia + +Copyright (c) 2011 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Harfbuzz + +Copyright © 2010-2022 Google, Inc. +Copyright © 2015-2020 Ebrahim Byagowi +Copyright © 2019,2020 Facebook, Inc. +Copyright © 2012,2015 Mozilla Foundation +Copyright © 2011 Codethink Limited +Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies) +Copyright © 2009 Keith Stribley +Copyright © 2011 Martin Hosken and SIL International +Copyright © 2007 Chris Wilson +Copyright © 2005,2006,2020,2021,2022,2023 Behdad Esfahbod +Copyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023 Red Hat, Inc. +Copyright © 1998-2005 David Turner and Werner Lemberg +Copyright © 2016 Igalia S.L. +Copyright © 2022 Matthias Clasen +Copyright © 2018,2021 Khaled Hosny +Copyright © 2018,2019,2020 Adobe, Inc +Copyright © 2013-2015 Alexei Podtelezhnikov + +For full copyright notices consult the individual files in the package. + + +Permission is hereby granted, without written agreement and without +license or royalty fees, to use, copy, modify, and distribute this +software and its documentation for any purpose, provided that the +above copyright notice and the following two paragraphs appear in +all copies of this software. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN +IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO +PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. diff --git a/README.md b/README.md index 6217895..4cf35ef 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# AlphaSkia +# alphaSkia > ℹ️ This library is still work in progress and not yet available. -AlphaSkia is a special cross platform [Skia](https://skia.org/) wrapper used in [AlphaTab](https://github.com/CoderLine/alphaTab) it aims to provide a HTML5 Canvas like API to alphaTab providing a consistent rendering experience across the alphaTab flavours like web, .net and Kotlin. Differences across operating systems might still apply. +alphaSkia is a special cross platform [Skia](https://skia.org/) wrapper used in [alphaTab](https://github.com/CoderLine/alphaTab) it aims to provide a HTML5 Canvas like API to alphaTab providing a consistent rendering experience across the alphaTab flavours like web, .net and Kotlin. Differences across operating systems might still apply. -A big **Thank you** to the following projects giving me good insights on how to build Skia in a cross platform fashion. These projects influenced heavily -how the pipelines of AlphaSkia are organized. +## Credits +A big _"Thank you"_ to the following projects giving me good insights on how to build Skia in a cross platform fashion. These projects influenced heavily how the pipelines of alphaSkia are organized. * [SkiaSharp](https://github.com/mono/SkiaSharp/) * [Skija](https://github.com/HumbleUI/Skija/) diff --git a/build/Build.DotNet.cs b/build/Build.DotNet.cs index 8683663..59890f2 100644 --- a/build/Build.DotNet.cs +++ b/build/Build.DotNet.cs @@ -1,4 +1,5 @@ using Nuke.Common; +using Nuke.Common.IO; using Nuke.Common.Tooling; using Nuke.Common.Tools.DotNet; @@ -32,10 +33,49 @@ partial class Build .DependsOn(PrepareGitHubArtifacts) .Executes(() => { + DotNetWriteVersionInfoProps(); + DotNetTasks.DotNetBuild(_ => _ .SetProcessWorkingDirectory(RootDirectory / "lib" / "dotnet") .SetConfiguration("Release") + .SetForce(Rebuild) ); }); - + + void DotNetWriteVersionInfoProps() + { + string semVer; + if (IsLocalBuild) + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}-local.{VersionInfo.FileVersion.Revision}"; + } + else if (!IsReleaseBuild) + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}-alpha.{VersionInfo.FileVersion.Revision}"; + } + else + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}"; + } + + var props = $""" + + + {semVer} + {VersionInfo.FileVersion.ToString(2)} + {VersionInfo.FileVersion.ToString(4)} + {VersionInfo.AuthorName} + {VersionInfo.Company} + {VersionInfo.ProductName} + {VersionInfo.Description} + {VersionInfo.Copyright} + {VersionInfo.LicenseSpdx} + {VersionInfo.ProjectUrl} + git + {VersionInfo.GitUrlHttp} + + + """; + (RootDirectory / "lib" / "dotnet" / "Version.props").WriteAllText(props); + } } \ No newline at end of file diff --git a/build/Build.Java.cs b/build/Build.Java.cs index 1be871a..2c2f2dc 100644 --- a/build/Build.Java.cs +++ b/build/Build.Java.cs @@ -29,7 +29,48 @@ partial class Build .DependsOn(PrepareGitHubArtifacts) .Executes(() => { + JavaWriteVersionInfoProperties(); + + if (Rebuild) + { + GradlewTool("clean", + workingDirectory: RootDirectory / "lib" / "java"); + } + GradlewTool("build", workingDirectory: RootDirectory / "lib" / "java"); }); + + void JavaWriteVersionInfoProperties() + { + string semVer; + if (IsLocalBuild) + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}-LOCAL"; + } + else if (!IsReleaseBuild) + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}-SNAPSHOT"; + } + else + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}"; + } + + var props = $""" + alphaskiaDescription={VersionInfo.Description} + alphaskiaAuthorId={VersionInfo.AuthorId} + alphaskiaAuthorName={VersionInfo.AuthorName} + alphaskiaOrgUrl={VersionInfo.OrgUrl} + alphaskiaCompany={VersionInfo.Company} + alphaskiaVersion={semVer} + alphaskiaProjectUrl={VersionInfo.ProjectUrl} + alphaskiaGitUrlHttp={VersionInfo.GitUrlHttp} + alphaskiaGitUrlGit"={VersionInfo.GitUrlGit} + alphaskiaLicenseSpdx={VersionInfo.LicenseSpdx} + alphaskiaLicenseUrl={VersionInfo.LicenseUrl} + alphaskiaIssuesUrl={VersionInfo.IssuesUrl} + """; + (RootDirectory / "lib" / "java" / "local.properties").WriteAllText(props); + } } \ No newline at end of file diff --git a/build/Build.LibAlphaSkia.cs b/build/Build.LibAlphaSkia.cs index 8971318..f483fb4 100644 --- a/build/Build.LibAlphaSkia.cs +++ b/build/Build.LibAlphaSkia.cs @@ -5,6 +5,7 @@ using System.Text; using Nuke.Common; using Nuke.Common.IO; +using Nuke.Common.Tooling; partial class Build { @@ -67,6 +68,9 @@ partial class Build "../../wrapper/src/alphaskia_typeface.cpp", "../../wrapper/src/alphaskia_data.cpp" ] + if (is_win) { + alphaskia_wrapper_sources += [ "../../wrapper/src/alphaskia.rc" ] + } config("alphaskia_public") { defines = [ "_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING", "ALPHASKIA_IMPLEMENTATION=1" ] include_dirs = [ "." ] @@ -77,7 +81,7 @@ partial class Build } if (is_win) { - libs = [ "skia.lib", "user32.lib", "OpenGL32.lib" ] + libs = [ "skia.lib", "user32.lib", "OpenGL32.lib", "alphaskia.rc.obj" ] } if (is_linux) { @@ -256,8 +260,8 @@ void BuildAlphaSkia() if (TargetOs == TargetOperatingSystem.Windows) { // TODO: check if clang-cl also works with the linux flags - AppendToFlagList(gnArgs, "extra_ldflags", - $"'/LIBPATH:{staticLibPath}'"); + AppendToFlagList(gnArgs, "extra_ldflags", $"'/LIBPATH:{staticLibPath}'"); + NativeWriteVersionInfoHeader(); } else { @@ -270,7 +274,32 @@ void BuildAlphaSkia() var outDir = SkiaPath / "out" / libDir; var libExtension = GetLibExtension(Variant); - GnNinja($"out/{libDir}", buildTarget, gnArgs, gnFlags, SkiaPath); + AbsolutePath rcOutputDir = null; + if (OperatingSystem.IsWindows() && TargetOs == TargetOperatingSystem.Windows) + { + rcOutputDir = outDir / "obj" / "alphaskia_wrapper"; + AppendToFlagList(gnArgs, "extra_ldflags", $"'/LIBPATH:{rcOutputDir}'"); + } + + GnNinja($"out/{libDir}", buildTarget, gnArgs, gnFlags, SkiaPath, + () => + { + if (OperatingSystem.IsWindows() && TargetOs == TargetOperatingSystem.Windows) + { + // compile resource file. Is is added as "library" in the BUILD.gn as input + // "llvm-rc.exe" /FO alphaskia.rc.obj alphaskia.rc /D RC_INVOKED /C 65001 + + var input = RootDirectory / "wrapper" / "src" / "alphaskia.rc"; + rcOutputDir.CreateDirectory(); + var output = rcOutputDir / "alphaskia.rc.obj"; + + const int utf8CodePage = 65001; + ToolResolver.GetTool((AbsolutePath)LlvmHome / "bin" / "llvm-rc.exe")( + $"/FO {output} {input} /D RC_INVOKED /C {utf8CodePage}", + workingDirectory: SkiaPath); + + } + }); try { @@ -298,6 +327,61 @@ void CopyBuildOutputTo(AbsolutePath path) } } + void NativeWriteVersionInfoHeader() + { + var libExtension = GetLibExtension(Variant); + + var versionInfo = new StringBuilder(); + versionInfo.AppendLine("#pragma once"); + versionInfo.AppendLine(""); + versionInfo.AppendLine( + $"#define VER_FILEVERSION {VersionInfo.FileVersion.Major},{VersionInfo.FileVersion.Minor},{VersionInfo.FileVersion.Build},{VersionInfo.FileVersion.Revision}"); + versionInfo.AppendLine( + $"#define VER_FILEVERSION_STR \"{VersionInfo.FileVersion.Major}.{VersionInfo.FileVersion.Minor}.{VersionInfo.FileVersion.Build}.{VersionInfo.FileVersion.Revision}\\0\""); + + versionInfo.AppendLine( + $"#define VER_PRODUCTVERSION {VersionInfo.FileVersion.Major},{VersionInfo.FileVersion.Minor},0,0"); + versionInfo.AppendLine( + $"#define VER_PRODUCTVERSION_STR \"{VersionInfo.FileVersion.Major}.{VersionInfo.FileVersion.Minor}\\0\""); + if (IsLocalBuild) + { + versionInfo.AppendLine("#define IS_LOCAL_BUILD 1"); + } + else if (IsReleaseBuild) + { + versionInfo.AppendLine("#define IS_RELEASE_BUILD 1"); + } + + versionInfo.AppendLine($"#define VER_COMPANY_STR \"{VersionInfo.Company}\""); + versionInfo.AppendLine($"#define VER_FILE_DESCRIPTION_STR \"{VersionInfo.Description}\""); + + if (Variant == Variant.Shared) + { + versionInfo.AppendLine("#define VER_INTERNALNAME_STR \"libalphaskia\""); + versionInfo.AppendLine($"#define VER_ORIGINALFILENAME_STR \"libalphaskia{libExtension}\""); + } + else if (Variant == Variant.Jni) + { + versionInfo.AppendLine("#define VER_INTERNALNAME_STR \"libalphaskiajni\""); + versionInfo.AppendLine($"#define VER_ORIGINALFILENAME_STR \"libalphaskiajni{libExtension}\""); + } + else if (Variant == Variant.Node) + { + versionInfo.AppendLine("#define VER_INTERNALNAME_STR \"libalphaskianode\""); + versionInfo.AppendLine($"#define VER_ORIGINALFILENAME_STR \"libalphaskianode{libExtension}\""); + } + + versionInfo.AppendLine($"#define VER_LEGALCOPYRIGHT_STR \"{VersionInfo.Copyright}\""); + versionInfo.AppendLine("#define VER_LEGALTRADEMARKS1_STR \"\""); + versionInfo.AppendLine("#define VER_LEGALTRADEMARKS2_STR \"\""); + versionInfo.AppendLine($"#define VER_PRODUCTNAME_STR \"{VersionInfo.Copyright}\""); + + var dir = RootDirectory / "wrapper" / "include" / "generated"; + dir.CreateDirectory(); + // NOTE: need guaranteed UTF-8 code page in this file + (dir / "version_info.h").WriteAllBytes(Encoding.UTF8.GetBytes(versionInfo.ToString())); + } + AbsolutePath DownloadNodeLib() { if (OperatingSystem.IsWindows() && TargetOs == TargetOperatingSystem.Windows) diff --git a/build/Build.Native.cs b/build/Build.Native.cs index 2519dc7..ae16e80 100644 --- a/build/Build.Native.cs +++ b/build/Build.Native.cs @@ -53,6 +53,8 @@ Tool GitTool [Parameter] readonly TargetOperatingSystem TargetOs; [Parameter] readonly Architecture Architecture; [Parameter] readonly Variant Variant; + [Parameter] readonly bool GnVerbose; + [Parameter] readonly bool NinjaVerbose; [Parameter(Name = "use-cache")] readonly string UseCacheParam; bool UseCache => "true".Equals(UseCacheParam, StringComparison.OrdinalIgnoreCase); @@ -220,7 +222,8 @@ Dictionary ReadDepsData(TextReader reader) void GnNinja(string outDir, string target, Dictionary gnArgs, Dictionary gnFlags, - AbsolutePath workingDirectory) + AbsolutePath workingDirectory, + Action beforeCompile = null) { gnArgs["skia_enable_tools"] = "false"; gnArgs["is_official_build"] = "true"; @@ -250,7 +253,18 @@ string QuoteValue(string value) gnFlags["script-executable"] = PythonExe; gnFlags["args"] = string.Join(" ", gnArgs.Select(o => $"{o.Key}={QuoteValue(o.Value)}")); - var gnFlagsString = string.Join(" ", gnFlags.Select(kvp => $"--{kvp.Key}={quote}{kvp.Value}{quote}")); + if (GnVerbose) + { + gnFlags["-v"] = ""; + } + + var gnFlagsString = string.Join(" ", gnFlags.Select(kvp => kvp.Value.Length > 0 ? $"--{kvp.Key}={quote}{kvp.Value}{quote}" : $"--{kvp.Key}")); + + if (Rebuild) + { + (SkiaPath / outDir).DeleteDirectory(); + } + // not inlined to avoid it being treated as FormattedString var gnToolArgs = $"gen {outDir} {gnFlagsString}"; @@ -261,7 +275,13 @@ string QuoteValue(string value) workingDirectory: workingDirectory ); - var ninjaArgs = $"-C {outDir} {target}"; + beforeCompile?.Invoke(); + + var ninjaArgs = $"-d keeprsp -C {outDir} {target}"; + if (NinjaVerbose) + { + ninjaArgs = "-v " + ninjaArgs; + } argument = new ArgumentStringHandler(ninjaArgs.Length, 0, out _); argument.AppendLiteral(ninjaArgs); NinjaTool( diff --git a/build/Build.Node.cs b/build/Build.Node.cs index 919af0e..c4abd3c 100644 --- a/build/Build.Node.cs +++ b/build/Build.Node.cs @@ -1,7 +1,10 @@ +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Unicode; using Nuke.Common; using Nuke.Common.IO; using Nuke.Common.Tooling; -using Nuke.Common.Tools.DotNet; using Nuke.Common.Tools.Npm; partial class Build @@ -9,15 +12,23 @@ partial class Build public Target Node => _ => _ .DependsOn(NodePack); + AbsolutePath[] AllNodePackages => new[] + { + RootDirectory / "lib" / "node" / "alphaskia", + RootDirectory / "lib" / "node" / "alphaskia-windows", + RootDirectory / "lib" / "node" / "alphaskia-linux", + RootDirectory / "lib" / "node" / "alphaskia-macos" + }; + public Target NodePack => _ => _ .Unlisted() .DependsOn(NodeTest) .Executes(() => { - NpmTasks.Npm("pack", RootDirectory / "lib" / "node" / "alphaskia"); - NpmTasks.Npm("pack", RootDirectory / "lib" / "node" / "alphaskia-windows"); - NpmTasks.Npm("pack", RootDirectory / "lib" / "node" / "alphaskia-linux"); - NpmTasks.Npm("pack", RootDirectory / "lib" / "node" / "alphaskia-macos"); + foreach (var nodePackage in AllNodePackages) + { + NpmTasks.Npm("pack", nodePackage); + } }); public Target NodeTest => _ => _ @@ -35,15 +46,22 @@ partial class Build .DependsOn(PrepareGitHubArtifacts) .Executes(() => { - NpmTasks.NpmInstall(_ => - _.SetProcessWorkingDirectory(RootDirectory / "lib" / "node" / "alphaskia")); - NpmTasks.NpmInstall(_ => - _.SetProcessWorkingDirectory(RootDirectory / "lib" / "node" / "alphaskia-windows")); - NpmTasks.NpmInstall(_ => - _.SetProcessWorkingDirectory(RootDirectory / "lib" / "node" / "alphaskia-linux")); - NpmTasks.NpmInstall(_ => - _.SetProcessWorkingDirectory(RootDirectory / "lib" / "node" / "alphaskia-macos")); + NodeWritePackageJson(); + if (Rebuild) + { + foreach (var nodePackage in AllNodePackages) + { + NpmTasks.Npm("clean", nodePackage); + } + } + + foreach (var nodePackage in AllNodePackages) + { + NpmTasks.NpmInstall(_ => + _.SetProcessWorkingDirectory(nodePackage)); + } + CopyNodeAddonsToPackages(); NpmTasks.NpmRun(_ => _ @@ -51,6 +69,59 @@ partial class Build .SetCommand("build")); }); + void NodeWritePackageJson() + { + string semVer; + if (IsLocalBuild) + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}-local.{VersionInfo.FileVersion.Revision}"; + } + else if (!IsReleaseBuild) + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}-alpha.{VersionInfo.FileVersion.Revision}"; + } + else + { + semVer = $"{VersionInfo.FileVersion.ToString(3)}"; + } + + var packageJsons = new[] + { + RootDirectory / "lib" / "node" / "alphaskia" / "package.json", + RootDirectory / "lib" / "node" / "alphaskia-linux" / "package.json", + RootDirectory / "lib" / "node" / "alphaskia-macos" / "package.json", + RootDirectory / "lib" / "node" / "alphaskia-windows" / "package.json" + }; + + foreach (var jsonPath in packageJsons) + { + var jsonContent = JsonNode.Parse(jsonPath.ReadAllText())!.AsObject(); + jsonContent["version"] = semVer; + jsonContent["homepage"] = VersionInfo.ProjectUrl; + jsonContent["bugs"] = new JsonObject + { + ["url"] = VersionInfo.IssuesUrl + }; + jsonContent["license"] = VersionInfo.LicenseSpdx; + jsonContent["author"] = new JsonObject + { + ["name"] = VersionInfo.AuthorName + }; + jsonContent["repository"] = new JsonObject + { + ["type"] = "git", + ["url"] = VersionInfo.GitUrlHttp, + ["directory"] = RootDirectory.GetRelativePathTo(jsonPath.Parent).ToUnixRelativePath().ToString() + }; + + jsonPath.WriteAllText(jsonContent.ToJsonString(new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + })); + } + } + void CopyNodeAddonsToPackages() { foreach (var subDirectory in DistBasePath.GetDirectories()) @@ -60,7 +131,7 @@ void CopyNodeAddonsToPackages() { continue; } - + string packageName; if (parts[1] == TargetOperatingSystem.Windows.RuntimeIdentifier) { diff --git a/build/Build.cs b/build/Build.cs index fc8f1df..9a9a67c 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -5,6 +5,24 @@ using Serilog; using static Nuke.Common.EnvironmentInfo; +static class VersionInfo +{ + public const string Company = "CoderLine"; + public const string Description = "A Skia based rendering backend for alphaTab."; + public static readonly Version FileVersion = GetVariable("VERSION") ?? new Version(1, 0, 0, 0); + public static readonly string Copyright = $"Copyright © {DateTime.Now.Year}, Daniel Kuschny"; + public const string AuthorId = "danielku15"; + public const string AuthorName = "Daniel Kuschny"; + public const string ProductName = "alphaSkia"; + public const string ProjectUrl = "https://github.com/CoderLine/alphaSkia"; + public const string GitUrlHttp = "https://github.com/CoderLine/alphaSkia.git"; + public const string GitUrlGit = "git://github.com/CoderLine/alphaSkia.git"; + public const string IssuesUrl = "https://github.com/CoderLine/alphaSkia/issues"; + public const string LicenseSpdx = "BSD-3-Clause"; + public const string LicenseUrl = "https://opensource.org/license/bsd-3-clause"; + public const string OrgUrl = "https://github.com/CoderLine"; +} + partial class Build : NukeBuild { // Path handling @@ -13,7 +31,10 @@ partial class Build : NukeBuild static readonly bool IsGitHubActions = GetVariable("GITHUB_ACTIONS"); static readonly AbsolutePath DistBasePath = RootDirectory / "dist"; static readonly AbsolutePath ArtifactBasePath = RootDirectory / "artifacts"; - + + [Parameter] readonly bool IsReleaseBuild = GetVariable("IS_RELEASE_BUILD") ?? false; + [Parameter] readonly bool Rebuild; + public static int Main() => Execute(); static void AppendToFlagList( diff --git a/lib/dotnet/AlphaSkia.Native.Android/AlphaSkia.Native.Android.csproj b/lib/dotnet/AlphaSkia.Native.Android/AlphaSkia.Native.Android.csproj index 6f0dec4..d53f258 100644 --- a/lib/dotnet/AlphaSkia.Native.Android/AlphaSkia.Native.Android.csproj +++ b/lib/dotnet/AlphaSkia.Native.Android/AlphaSkia.Native.Android.csproj @@ -1,10 +1,10 @@ true - false netstandard2.0 README.md - $(NoWarn);NU5128 + true + $(ProductDescription) This package contains the AlphaSkia runtime dependencies for Android. diff --git a/lib/dotnet/AlphaSkia.Native.Android/README.md b/lib/dotnet/AlphaSkia.Native.Android/README.md index 3b36ba7..5545437 100644 --- a/lib/dotnet/AlphaSkia.Native.Android/README.md +++ b/lib/dotnet/AlphaSkia.Native.Android/README.md @@ -1,3 +1,3 @@ -# AlphaSkia Android Runtime Dependencies +# alphaSkia Android Runtime Dependencies -This package contains the AlphaSkia runtime dependencies for Android. \ No newline at end of file +This package contains the alphaSkia runtime dependencies for Android. \ No newline at end of file diff --git a/lib/dotnet/AlphaSkia.Native.Linux/AlphaSkia.Native.Linux.csproj b/lib/dotnet/AlphaSkia.Native.Linux/AlphaSkia.Native.Linux.csproj index 8b3d2c2..16bea20 100644 --- a/lib/dotnet/AlphaSkia.Native.Linux/AlphaSkia.Native.Linux.csproj +++ b/lib/dotnet/AlphaSkia.Native.Linux/AlphaSkia.Native.Linux.csproj @@ -1,10 +1,10 @@ true - false netstandard2.0 README.md - $(NoWarn);NU5128 + true + $(ProductDescription) This package contains the alphaSkia runtime dependencies for Linux. diff --git a/lib/dotnet/AlphaSkia.Native.Linux/README.md b/lib/dotnet/AlphaSkia.Native.Linux/README.md index a3b4da2..f17358f 100644 --- a/lib/dotnet/AlphaSkia.Native.Linux/README.md +++ b/lib/dotnet/AlphaSkia.Native.Linux/README.md @@ -1,3 +1,3 @@ -# AlphaSkia Linux Runtime Dependencies +# alphaSkia Linux Runtime Dependencies -This package contains the AlphaSkia runtime dependencies for Linux \ No newline at end of file +This package contains the alphaSkia runtime dependencies for Linux \ No newline at end of file diff --git a/lib/dotnet/AlphaSkia.Native.MacOs/AlphaSkia.Native.MacOs.csproj b/lib/dotnet/AlphaSkia.Native.MacOs/AlphaSkia.Native.MacOs.csproj index 53fc8db..40b275d 100644 --- a/lib/dotnet/AlphaSkia.Native.MacOs/AlphaSkia.Native.MacOs.csproj +++ b/lib/dotnet/AlphaSkia.Native.MacOs/AlphaSkia.Native.MacOs.csproj @@ -1,10 +1,10 @@ true - false netstandard2.0 README.md - $(NoWarn);NU5128 + true + $(ProductDescription) This package contains the alphaSkia runtime dependencies for MacOS. diff --git a/lib/dotnet/AlphaSkia.Native.MacOs/README.md b/lib/dotnet/AlphaSkia.Native.MacOs/README.md index a3b4da2..f17358f 100644 --- a/lib/dotnet/AlphaSkia.Native.MacOs/README.md +++ b/lib/dotnet/AlphaSkia.Native.MacOs/README.md @@ -1,3 +1,3 @@ -# AlphaSkia Linux Runtime Dependencies +# alphaSkia Linux Runtime Dependencies -This package contains the AlphaSkia runtime dependencies for Linux \ No newline at end of file +This package contains the alphaSkia runtime dependencies for Linux \ No newline at end of file diff --git a/lib/dotnet/AlphaSkia.Native.Windows/AlphaSkia.Native.Windows.csproj b/lib/dotnet/AlphaSkia.Native.Windows/AlphaSkia.Native.Windows.csproj index 959eb3d..3b4d817 100644 --- a/lib/dotnet/AlphaSkia.Native.Windows/AlphaSkia.Native.Windows.csproj +++ b/lib/dotnet/AlphaSkia.Native.Windows/AlphaSkia.Native.Windows.csproj @@ -1,10 +1,10 @@ true - false netstandard2.0 README.md - $(NoWarn);NU5128 + true + $(ProductDescription) This package contains the alphaSkia runtime dependencies for Windows. diff --git a/lib/dotnet/AlphaSkia.Native.Windows/README.md b/lib/dotnet/AlphaSkia.Native.Windows/README.md index 843bd34..12e7556 100644 --- a/lib/dotnet/AlphaSkia.Native.Windows/README.md +++ b/lib/dotnet/AlphaSkia.Native.Windows/README.md @@ -1,3 +1,3 @@ -# AlphaSkia Windows Runtime Dependencies +# alphaSkia Windows Runtime Dependencies -This package contains the AlphaSkia runtime dependencies for Windows \ No newline at end of file +This package contains the alphaSkia runtime dependencies for Windows \ No newline at end of file diff --git a/lib/dotnet/AlphaSkia.Native.iOS/AlphaSkia.Native.iOS.csproj b/lib/dotnet/AlphaSkia.Native.iOS/AlphaSkia.Native.iOS.csproj index 9614f02..a6827e4 100644 --- a/lib/dotnet/AlphaSkia.Native.iOS/AlphaSkia.Native.iOS.csproj +++ b/lib/dotnet/AlphaSkia.Native.iOS/AlphaSkia.Native.iOS.csproj @@ -1,10 +1,10 @@ true - false netstandard2.0 README.md - $(NoWarn);NU5128 + true + $(ProductDescription) This package contains the AlphaSkia runtime dependencies for iOS. diff --git a/lib/dotnet/AlphaSkia.Native.iOS/README.md b/lib/dotnet/AlphaSkia.Native.iOS/README.md index c531cb7..31ee247 100644 --- a/lib/dotnet/AlphaSkia.Native.iOS/README.md +++ b/lib/dotnet/AlphaSkia.Native.iOS/README.md @@ -1,3 +1,3 @@ -# AlphaSkia iOS Runtime Dependencies +# alphaSkia iOS Runtime Dependencies -This package contains the AlphaSkia runtime dependencies for iOS \ No newline at end of file +This package contains the alphaSkia runtime dependencies for iOS \ No newline at end of file diff --git a/lib/dotnet/AlphaSkia/AlphaSkia.csproj b/lib/dotnet/AlphaSkia/AlphaSkia.csproj index cd5c2a9..a99bdb2 100644 --- a/lib/dotnet/AlphaSkia/AlphaSkia.csproj +++ b/lib/dotnet/AlphaSkia/AlphaSkia.csproj @@ -8,6 +8,8 @@ README.md true 10 + $(ProductDescription) + true diff --git a/lib/dotnet/AlphaSkia/AlphaSkiaCanvas.cs b/lib/dotnet/AlphaSkia/AlphaSkiaCanvas.cs index 7ae64a9..546e24b 100644 --- a/lib/dotnet/AlphaSkia/AlphaSkiaCanvas.cs +++ b/lib/dotnet/AlphaSkia/AlphaSkiaCanvas.cs @@ -84,7 +84,7 @@ public float LineWidth /// /// The width of the image to produce. /// The height of the image to produce. - /// The scale factor for the image (e.g. for high DPI rendering with keeping cooridnatess). + /// The scale factor for the image (e.g. for high DPI rendering with keeping coordinates). public void BeginRender(int width, int height, float renderScale = 1) { CheckDisposed(); @@ -201,7 +201,7 @@ public void QuadraticCurveTo(float cpx, float cpy, float x, float y) } /// - /// Draws a bezier curve from the current path position to the given position. + /// Draws a Bézier curve from the current path position to the given position. /// /// The X-position of the first control point. /// The Y-position of the first control point. diff --git a/lib/dotnet/AlphaSkia/AlphaSkiaNative.cs b/lib/dotnet/AlphaSkia/AlphaSkiaNative.cs index 3d763db..7356f77 100644 --- a/lib/dotnet/AlphaSkia/AlphaSkiaNative.cs +++ b/lib/dotnet/AlphaSkia/AlphaSkiaNative.cs @@ -1,4 +1,6 @@ -namespace AlphaSkia; +using System.ComponentModel; + +namespace AlphaSkia; /// /// The base class for AlphaSkia objects wrapping native Skia objects. @@ -21,22 +23,36 @@ private void ReleaseUnmanagedResources() Native = IntPtr.Zero; } + /// + /// Releases the unmanaged resources used by this instnace and optionally releases the managed resources. + /// + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + /// protected virtual void Dispose(bool disposing) { ReleaseUnmanagedResources(); } + /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } + /// + /// Releases unmanaged resources and performs other cleanup operations before this instance is reclaimed by garbage collection. + /// ~AlphaSkiaNative() { Dispose(false); } - + + /// + /// Checks whether the object has already been disposed and throws an exception if so. + /// + /// Thrown if this instance was already disposed. protected void CheckDisposed() { if (Native == IntPtr.Zero) diff --git a/lib/dotnet/AlphaSkia/AlphaSkiaPlatform.cs b/lib/dotnet/AlphaSkia/AlphaSkiaPlatform.cs index 82c00a5..cdacb10 100644 --- a/lib/dotnet/AlphaSkia/AlphaSkiaPlatform.cs +++ b/lib/dotnet/AlphaSkia/AlphaSkiaPlatform.cs @@ -4,7 +4,7 @@ namespace AlphaSkia; /// /// This class provides a manual way of resolving and loading the native libraries required -/// by AlphaSkia. If AlphaSkia is installed via NuGet it should automatically resolve the +/// by alphaSkia. If alphaSkia is installed via NuGet it should automatically resolve the /// DLLs, but if this fails developers can call to activate the manual loading procedure. /// public static class AlphaSkiaPlatform diff --git a/lib/dotnet/AlphaSkia/AlphaSkiaTypeface.cs b/lib/dotnet/AlphaSkia/AlphaSkiaTypeface.cs index f525b53..0d7d5e5 100644 --- a/lib/dotnet/AlphaSkia/AlphaSkiaTypeface.cs +++ b/lib/dotnet/AlphaSkia/AlphaSkiaTypeface.cs @@ -13,6 +13,7 @@ private AlphaSkiaTypeface(IntPtr native, AlphaSkiaData? nativeData = null) _nativeData = nativeData; } + /// protected override void Dispose(bool disposing) { base.Dispose(disposing); @@ -22,6 +23,11 @@ protected override void Dispose(bool disposing) } } + /// + /// Register a new custom font from the given binary data containing the data of a font compatible with Skia (e.g. TTF). + /// + /// The raw binary data of the font. + /// The loaded typeface to use for text rendering or null if the loading failed. public static AlphaSkiaTypeface? Register(byte[] data) { var nativeData = NativeMethods.alphaskia_data_new_copy(data, (ulong)data.LongLength); @@ -34,7 +40,14 @@ protected override void Dispose(bool disposing) return new AlphaSkiaTypeface(typeface, new AlphaSkiaData(nativeData)); } - + + /// + /// Creates a typeface using the provided information. + /// + /// The name of the typeface. + /// Whether the bold version of the typeface should be loaded. + /// Whether the italic version of the typeface should be loaded. + /// The typeface if it can be found in the already loaded fonts or the system fonts, otherwise null. public static AlphaSkiaTypeface? Create(string name, bool bold, bool italic) { var typeface = diff --git a/lib/dotnet/AlphaSkia/README.md b/lib/dotnet/AlphaSkia/README.md index f54dae8..968f832 100644 --- a/lib/dotnet/AlphaSkia/README.md +++ b/lib/dotnet/AlphaSkia/README.md @@ -1,6 +1,6 @@ -# AlphaSkia +# alphaSkia -AlphaSkia is a cross platform Skia wrapper used in alphaTab to provide a consistent +alphaSkia is a cross platform Skia wrapper used in alphaTab to provide a consistent rendering experience across the different platforms supported by alphaTab. It's a lightweight HTML5 Canvas inspired API for drawing images utilizing Skia als rendering backend. \ No newline at end of file diff --git a/lib/dotnet/Directory.Build.props b/lib/dotnet/Directory.Build.props index 97b359d..cd62c37 100644 --- a/lib/dotnet/Directory.Build.props +++ b/lib/dotnet/Directory.Build.props @@ -1,5 +1,15 @@ + + portable + true + 1.0.0 + $(Version).0 + $(AssemblyVersion) + en + true + snupkg + true $(MSBuildThisFileDirectory)/../../dist/ diff --git a/lib/java/.idea/inspectionProfiles/Project_Default.xml b/lib/java/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..1509479 --- /dev/null +++ b/lib/java/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/lib/java/android/build.gradle.kts b/lib/java/android/build.gradle.kts index 1778995..30b2175 100644 --- a/lib/java/android/build.gradle.kts +++ b/lib/java/android/build.gradle.kts @@ -1,11 +1,15 @@ plugins { id("java-library") + `maven-publish` + signing } java { toolchain{ languageVersion.set(JavaLanguageVersion.of(17)) } + withSourcesJar() + withJavadocJar() } tasks.jar { diff --git a/lib/java/android/src/main/java/net/alphatab/alphaskia/AlphaSkiaAndroid.java b/lib/java/android/src/main/java/net/alphatab/alphaskia/AlphaSkiaAndroid.java index fc7acbe..ef17a60 100644 --- a/lib/java/android/src/main/java/net/alphatab/alphaskia/AlphaSkiaAndroid.java +++ b/lib/java/android/src/main/java/net/alphatab/alphaskia/AlphaSkiaAndroid.java @@ -1,6 +1,12 @@ package net.alphatab.alphaskia; -public class AlphaSkiaAndroid { +/** + * This class contains the information about the Android runtime dependencies to use with AlphaSkiaPlatform. + */ +public final class AlphaSkiaAndroid { + /** + * The native libraries needed to run alphaSkia. + */ public static final String[] libraries = { "native/android-" + getCurrentArchitecture() + "/libalphaskiajni.so" }; @@ -15,4 +21,6 @@ private static String getCurrentArchitecture() { default -> jarch; }; } + + private AlphaSkiaAndroid() {} } diff --git a/lib/java/build.gradle.kts b/lib/java/build.gradle.kts index 2b36008..da9e4a0 100644 --- a/lib/java/build.gradle.kts +++ b/lib/java/build.gradle.kts @@ -1,4 +1,6 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import java.io.FileInputStream +import java.util.* buildscript { repositories { @@ -8,15 +10,89 @@ buildscript { } } + +var sonatypeSigningKeyId = "" +var sonatypeSigningPassword = "" +var sonatypeSigningKey = "" +var ossrhUsername = "" +var ossrhPassword = "" +var sonatypeStagingProfileId = "" + +var libDescription = "" +var libAuthorId = "" +var libAuthorName = "" +var libOrgUrl = "" +var libCompany = "" +var libVersion = "" +var libProjectUrl = "" +var libGitUrlHttp = "" +var libGitUrlGit = "" +var libLicenseSpdx = "" +var libLicenseUrl = "" +var libIssuesUrl = "" + +val props = Properties() +val propsFile = project.rootProject.file("local.properties") +if (propsFile.exists()) { + FileInputStream(propsFile).use { + props.load(it) + } +} + +fun loadSetting(envKey: String, propKey: String, setter: (value: String) -> Unit) { + if (props.containsKey(propKey)) { + setter(props.getProperty(propKey)) + } else { + val env = providers + .environmentVariable(envKey) + if (env.isPresent) { + setter(env.get()) + } + } +} + +loadSetting("OSSRH_USERNAME", "ossrhUsername") { ossrhUsername = it } +loadSetting("OSSRH_PASSWORD", "ossrhPassword") { ossrhPassword = it } +loadSetting("SONATYPE_STAGING_PROFILE_ID", "sonatypeStagingProfileId") { sonatypeStagingProfileId = it } +loadSetting("SONATYPE_SIGNING_KEY_ID", "sonatypeSigningKeyId") { sonatypeSigningKeyId = it } +loadSetting("SONATYPE_SIGNING_PASSWORD", "sonatypeSigningPassword") { sonatypeSigningPassword = it } +loadSetting("SONATYPE_SIGNING_KEY", "sonatypeSigningKey") { sonatypeSigningKey = it } +loadSetting("ALPHASKIA_DESCRIPTION", "alphaskiaDescription") { libDescription = it } +loadSetting("ALPHASKIA_AUTHOR_ID", "alphaskiaAuthorId") { libAuthorId = it } +loadSetting("ALPHASKIA_AUTHOR_NAME", "alphaskiaAuthorName") { libAuthorName = it } +loadSetting("ALPHASKIA_ORG_URL", "alphaskiaOrgUrl") { libOrgUrl = it } +loadSetting("ALPHASKIA_COMPANY", "alphaskiaCompany") { libCompany = it } +loadSetting("ALPHASKIA_VERSION", "alphaskiaVersion") { libVersion = it } +loadSetting("ALPHASKIA_PROJECT_URL", "alphaskiaProjectUrl") { libProjectUrl = it } +loadSetting("ALPHASKIA_GIT_URL_HTTP", "alphaskiaGitUrlHttp") { libGitUrlHttp = it } +loadSetting("ALPHASKIA_GIT_URL_GIT", "alphaskiaGitUrlGit") { libGitUrlGit = it } +loadSetting("ALPHASKIA_LICENSE_SPDX", "alphaskiaLicenseSpdx") { libLicenseSpdx = it } +loadSetting("ALPHASKIA_LICENSE_URL", "alphaskiaLicenseUrl") { libLicenseUrl = it } +loadSetting("ALPHASKIA_ISSUES_URL", "alphaskiaIssuesUrl") { libIssuesUrl = it } + + + subprojects { + apply() + apply() + apply(plugin = "maven-publish") + group = "net.alphatab" - version = "1.0-SNAPSHOT" + version = libVersion repositories { google() mavenCentral() } + configure { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } + withSourcesJar() + withJavadocJar() + } + tasks.withType().configureEach { systemProperty("alphaskia.library.path", rootProject.projectDir.resolve("../../dist/")) systemProperty("testdata.path", rootProject.projectDir.resolve("../test/")) @@ -26,4 +102,64 @@ subprojects { showStackTraces = true } } -} \ No newline at end of file + + configure { + repositories { +// maven { +// name = "sonatype" +// url = uri( +// if (libVersion.endsWith("SNAPSHOT")) +// "https://s01.oss.sonatype.org/content/repositories/snapshots/" +// else +// "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" +// ) +// credentials { +// username = ossrhUsername +// password = ossrhPassword +// } +// } + + maven { + name = "DistPath" + url = rootProject.projectDir.resolve("dist").toURI() + } + } + + publications { + create("mavenJava") { + from(components["java"]) + afterEvaluate { + artifactId = tasks.withType().first().archiveBaseName.get() + + pom { + description = libDescription + url = libProjectUrl + licenses { + license { + name = libLicenseSpdx + url = libLicenseUrl + } + } + developers { + developer { + id = libAuthorId + name = libAuthorName + organization = libCompany + organizationUrl = libOrgUrl + } + } + scm { + url = libGitUrlHttp + connection = "scm:git:$libGitUrlGit" + developerConnection = "scm:git:$libGitUrlGit" + } + issueManagement { + system = "GitHub" + url = libIssuesUrl + } + } + } + } + } + } +} diff --git a/lib/java/linux/build.gradle.kts b/lib/java/linux/build.gradle.kts index 4eafb47..ccd2588 100644 --- a/lib/java/linux/build.gradle.kts +++ b/lib/java/linux/build.gradle.kts @@ -1,11 +1,15 @@ plugins { id("java-library") + `maven-publish` + signing } java { toolchain{ languageVersion.set(JavaLanguageVersion.of(17)) } + withSourcesJar() + withJavadocJar() } tasks.jar { diff --git a/lib/java/linux/src/main/java/net/alphatab/alphaskia/AlphaSkiaLinux.java b/lib/java/linux/src/main/java/net/alphatab/alphaskia/AlphaSkiaLinux.java index 29d19a0..5bd3f26 100644 --- a/lib/java/linux/src/main/java/net/alphatab/alphaskia/AlphaSkiaLinux.java +++ b/lib/java/linux/src/main/java/net/alphatab/alphaskia/AlphaSkiaLinux.java @@ -1,6 +1,12 @@ package net.alphatab.alphaskia; +/** + * This class contains the information about the Linux runtime dependencies to use with AlphaSkiaPlatform. + */ public class AlphaSkiaLinux { + /** + * The native libraries needed to run alphaSkia. + */ public static final String[] libraries = { "native/linux-" + getCurrentArchitecture() + "/libalphaskiajni.so" }; diff --git a/lib/java/macos/build.gradle.kts b/lib/java/macos/build.gradle.kts index 6096ca3..3658cf4 100644 --- a/lib/java/macos/build.gradle.kts +++ b/lib/java/macos/build.gradle.kts @@ -1,11 +1,15 @@ plugins { id("java-library") + `maven-publish` + signing } java { toolchain{ languageVersion.set(JavaLanguageVersion.of(17)) } + withSourcesJar() + withJavadocJar() } tasks.jar { diff --git a/lib/java/macos/src/main/java/net/alphatab/alphaskia/AlphaSkiaMacOs.java b/lib/java/macos/src/main/java/net/alphatab/alphaskia/AlphaSkiaMacOs.java index 274bf29..4bd7d91 100644 --- a/lib/java/macos/src/main/java/net/alphatab/alphaskia/AlphaSkiaMacOs.java +++ b/lib/java/macos/src/main/java/net/alphatab/alphaskia/AlphaSkiaMacOs.java @@ -1,8 +1,14 @@ package net.alphatab.alphaskia; -public class AlphaSkiaMacOs { +/** + * This class contains the information about the macOS runtime dependencies to use with AlphaSkiaPlatform. + */ +public final class AlphaSkiaMacOs { + /** + * The native libraries needed to run alphaSkia. + */ public static final String[] libraries = { - "native/macos-" + getCurrentArchitecture() + "/libalphaskiajni.so" + "native/macos-" + getCurrentArchitecture() + "/libalphaskiajni.dylib" }; private static String getCurrentArchitecture() { @@ -15,4 +21,6 @@ private static String getCurrentArchitecture() { default -> jarch; }; } + + private AlphaSkiaMacOs() {} } diff --git a/lib/java/main/build.gradle.kts b/lib/java/main/build.gradle.kts index ff86134..e8903d4 100644 --- a/lib/java/main/build.gradle.kts +++ b/lib/java/main/build.gradle.kts @@ -1,15 +1,19 @@ plugins { id("java-library") + `maven-publish` + signing } java { - toolchain{ - languageVersion.set(JavaLanguageVersion.of(17)) + toolchain { + languageVersion = JavaLanguageVersion.of(17) } + withSourcesJar() + withJavadocJar() } tasks.withType().configureEach { - options.headerOutputDirectory.set(rootProject.projectDir.resolve("jni/include")) + options.headerOutputDirectory = rootProject.projectDir.resolve("jni/include") } dependencies { diff --git a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaCanvas.java b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaCanvas.java index d3f7da8..8991876 100644 --- a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaCanvas.java +++ b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaCanvas.java @@ -7,8 +7,9 @@ public class AlphaSkiaCanvas extends AlphaSkiaNative { private static AlphaSkiaColorType colorType; /** - * Gets or sets the {@link AlphaSkiaColorType} used when generating images. + * Gets the {@link AlphaSkiaColorType} used when generating images. * AlphaSkia tries to use the native color tpe of the system but this can vary based on OS. + * @return The {@link AlphaSkiaColorType} used when generating images */ public static AlphaSkiaColorType getColorType() { if (colorType == null) { @@ -19,13 +20,15 @@ public static AlphaSkiaColorType getColorType() { /** * Gets the color to use for drawing operations in the native canvas. - * See also @{link rgbaToColor} + * See also {@link #rgbaToColor} + * @return The color to use for drawing operations in the native canvas */ public native int getColor(); /** * Sets the color to use for drawing operations in the native canvas. - * See also @{link rgbaToColor} + * See also {@link #rgbaToColor} + * @param color The color to use for drawing operations in the native canvas. */ public native void setColor(int color); @@ -36,22 +39,28 @@ public static AlphaSkiaColorType getColorType() { * @param g The green component of the color. * @param b The blue component of the color. * @param a The alpha channel of the color. + * @return The encoded color. */ public static int rgbaToColor(byte r, byte g, byte b, byte a) { return (((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | - ((b & 0xFF) << 0)); + (b & 0xFF)); } /** * Gets the line width to use when drawing strokes and lines. + * @return The line width to use when drawing strokes and lines. */ public native float getLineWidth(); /** * Sets the line width to use when drawing strokes and lines. + * @param lineWidth The line width to use when drawing strokes and lines */ public native void setLineWidth(float lineWidth); + /** + * Initializes a new empty canvas to use for drawing. + */ public AlphaSkiaCanvas() { super(alphaskiaCanvasAllocate()); } @@ -75,7 +84,7 @@ public void beginRender(int width, int height) * * @param width The width of the image to produce. * @param height The height of the image to produce. - * @param scaleFactor The scale factor for the image (e.g. for high DPI rendering with keeping cooridnatess). + * @param scaleFactor The scale factor for the image (e.g. for high DPI rendering with keeping coordinates). */ public native void beginRender(int width, int height, float scaleFactor); @@ -93,7 +102,7 @@ public void beginRender(int width, int height) /** * Ends the rendering session and provides the rendered result. * - * @return The rendered result or null if something went wrong. + * @return The rendered result or {@code null} if something went wrong. */ public native AlphaSkiaImage endRender(); @@ -154,7 +163,7 @@ public void beginRender(int width, int height) public native void quadraticCurveTo(float cpx, float cpy, float x, float y); /** - * Draws a bezier curve from the current path position to the given position. + * Draws a Bézier curve from the current path position to the given position. * * @param cp1X The X-position of the first control point. * @param cp1Y The Y-position of the first control point. @@ -228,7 +237,7 @@ public native void fillText(String text, AlphaSkiaTypeface typeface, float fontS public native void beginRotate(float centerX, float centerY, float angle); /** - * Restores the previous rotation state after was called. + * Restores the previous rotation state after {@link #beginRotate} was called. */ public native void endRotate(); diff --git a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaColorType.java b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaColorType.java index 11ff60d..35b4e30 100644 --- a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaColorType.java +++ b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaColorType.java @@ -27,7 +27,7 @@ int getValue() { this.value = value; } - public static AlphaSkiaColorType fromValue(int value) { + static AlphaSkiaColorType fromValue(int value) { if (value == RGBA_8888.getValue()) { return RGBA_8888; } else if (value == BGRA_8888.getValue()) { diff --git a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaNative.java b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaNative.java index 3adf6a5..49a357d 100644 --- a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaNative.java +++ b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaNative.java @@ -10,9 +10,9 @@ public abstract class AlphaSkiaNative implements AutoCloseable { } } - protected long handle; + long handle; - protected AlphaSkiaNative(long handle) { + AlphaSkiaNative(long handle) { this.handle = handle; } diff --git a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaPlatform.java b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaPlatform.java index 1d2bc0d..0142ed7 100644 --- a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaPlatform.java +++ b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaPlatform.java @@ -9,17 +9,32 @@ import java.nio.file.Path; import java.nio.file.Paths; +/** + * This class provides a way of resolving and loading the native libraries required + * by alphaSkia. + */ public final class AlphaSkiaPlatform { private static boolean nativeLibLoaded = false; + /** + * Gets a value indicating whether the native libraries required by alphaSkia were loaded. + * + * @return {@code true} if the libraries were loaded, otherwise {@code false}. + */ public static boolean isNativeLibLoaded() { return nativeLibLoaded; } + /** + * Initiates the loading of native libraries from the given file paths assuming they are the correct ones for alphaSkia. + * + * @param nativeLibraryPaths The paths to the files to load. + * @throws IOException Thrown if any of the paths provided point to a non-existent file. + */ public static void loadLibrary(String[] nativeLibraryPaths) throws IOException { - for(String library : nativeLibraryPaths) { + for (String library : nativeLibraryPaths) { var file = new File(library); - if(!file.exists()){ + if (!file.exists()) { throw new FileNotFoundException("Could not find file: " + library); } System.load(library); @@ -27,6 +42,15 @@ public static void loadLibrary(String[] nativeLibraryPaths) throws IOException { nativeLibLoaded = true; } + /** + * Initiates loading of native libraries from the given platform information class shipped as part of + * individual alphaSkia platform packages. + * + * @param platformInfo The platform info class like {@code net.alphatab.alphaskia.ALphaSkiaWindows} provided + * through individual platform packages. + * @throws IOException Thrown if the resources expected to be provided by the platform package could not be found or extracted. + * @throws IllegalArgumentException Thrown if the provided platform info class is not compliant with the needs of alphaSkia. Indicates typically an incompatibility or a wrong class being provided. + */ public static void loadLibrary(Class platformInfo) throws IOException { try { String[] libraries = (String[]) platformInfo.getDeclaredField("libraries").get(null); diff --git a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaTextBaseline.java b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaTextBaseline.java index b456acb..10c6181 100644 --- a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaTextBaseline.java +++ b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaTextBaseline.java @@ -22,7 +22,6 @@ public enum AlphaSkiaTextBaseline { */ BOTTOM(3); - private final int value; int getValue() { diff --git a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaTypeface.java b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaTypeface.java index a8bcb20..55bffd7 100644 --- a/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaTypeface.java +++ b/lib/java/main/src/main/java/net/alphatab/alphaskia/AlphaSkiaTypeface.java @@ -1,5 +1,8 @@ package net.alphatab.alphaskia; +/** + * Represents a typeface to draw text. + */ public class AlphaSkiaTypeface extends AlphaSkiaNative { private final AlphaSkiaData data; @@ -20,6 +23,11 @@ public void close() { private native void release(long handle); + /** + * Register a new custom font from the given binary data containing the data of a font compatible with Skia (e.g. TTF). + * @param data The raw binary data of the font. + * @return The loaded typeface to use for text rendering or {@code null} if the loading failed. + */ public static AlphaSkiaTypeface register(byte[] data) { var nativeData = new AlphaSkiaData(data); var typeface = register(nativeData.handle); @@ -32,6 +40,13 @@ public static AlphaSkiaTypeface register(byte[] data) { private static native long register(long handle); + /** + * Creates a typeface using the provided information. + * @param name The name of the typeface. + * @param bold Whether the bold version of the typeface should be loaded. + * @param italic Whether the italic version of the typeface should be loaded. + * @return The typeface if it can be found in the already loaded fonts or the system fonts, otherwise {@code null}. + */ public static AlphaSkiaTypeface create(String name, boolean bold, boolean italic) { var typeface = makeFromName(name, bold, italic); if (typeface == 0) { diff --git a/lib/java/windows/build.gradle.kts b/lib/java/windows/build.gradle.kts index f7a45c2..6b9982b 100644 --- a/lib/java/windows/build.gradle.kts +++ b/lib/java/windows/build.gradle.kts @@ -1,13 +1,18 @@ plugins { id("java-library") + `maven-publish` + signing } java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } + withSourcesJar() + withJavadocJar() } + tasks.jar { archiveBaseName = "net.alphatab.alphaskia.windows" diff --git a/lib/java/windows/src/main/java/net/alphatab/alphaskia/AlphaSkiaWindows.java b/lib/java/windows/src/main/java/net/alphatab/alphaskia/AlphaSkiaWindows.java index a7671ee..593bc11 100644 --- a/lib/java/windows/src/main/java/net/alphatab/alphaskia/AlphaSkiaWindows.java +++ b/lib/java/windows/src/main/java/net/alphatab/alphaskia/AlphaSkiaWindows.java @@ -1,6 +1,12 @@ package net.alphatab.alphaskia; -public class AlphaSkiaWindows { +/** + * This class contains the information about the Windows runtime dependencies to use with AlphaSkiaPlatform. + */ +public final class AlphaSkiaWindows { + /** + * The native libraries needed to run alphaSkia. + */ public static final String[] libraries = { "native/windows-" + getCurrentArchitecture() + "/libalphaskiajni.dll" }; @@ -15,4 +21,6 @@ private static String getCurrentArchitecture() { default -> jarch; }; } + + private AlphaSkiaWindows() {} } diff --git a/lib/node/alphaskia-linux/package.json b/lib/node/alphaskia-linux/package.json index b3e1b54..eede366 100644 --- a/lib/node/alphaskia-linux/package.json +++ b/lib/node/alphaskia-linux/package.json @@ -7,14 +7,17 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/CoderLine/alphaSkia.git" + "url": "https://github.com/CoderLine/alphaSkia.git", + "directory": "lib/node/alphaskia-linux" + }, + "author": { + "name": "Daniel Kuschny" }, - "author": "Daniel Kuschny", "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/CoderLine/alphaSkia/issues" }, - "homepage": "https://github.com/CoderLine/alphaSkia#readme", + "homepage": "https://github.com/CoderLine/alphaSkia", "files": [ "/lib/libalphaskianode-linux-x64-node/libalphaskianode.node", "/lib/libalphaskianode-linux-x86-node/libalphaskianode.node", diff --git a/lib/node/alphaskia-macos/package.json b/lib/node/alphaskia-macos/package.json index c2d0dff..40ab9ec 100644 --- a/lib/node/alphaskia-macos/package.json +++ b/lib/node/alphaskia-macos/package.json @@ -7,14 +7,17 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/CoderLine/alphaSkia.git" + "url": "https://github.com/CoderLine/alphaSkia.git", + "directory": "lib/node/alphaskia-macos" + }, + "author": { + "name": "Daniel Kuschny" }, - "author": "Daniel Kuschny", "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/CoderLine/alphaSkia/issues" }, - "homepage": "https://github.com/CoderLine/alphaSkia#readme", + "homepage": "https://github.com/CoderLine/alphaSkia", "files": [ "/lib/libalphaskianode-macos-x64-node/libalphaskianode.node", "/lib/libalphaskianode-macos-arm64-node/libalphaskianode.node" diff --git a/lib/node/alphaskia-windows/package.json b/lib/node/alphaskia-windows/package.json index 633d4f9..00ef692 100644 --- a/lib/node/alphaskia-windows/package.json +++ b/lib/node/alphaskia-windows/package.json @@ -7,14 +7,17 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/CoderLine/alphaSkia.git" + "url": "https://github.com/CoderLine/alphaSkia.git", + "directory": "lib/node/alphaskia-windows" + }, + "author": { + "name": "Daniel Kuschny" }, - "author": "Daniel Kuschny", "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/CoderLine/alphaSkia/issues" }, - "homepage": "https://github.com/CoderLine/alphaSkia#readme", + "homepage": "https://github.com/CoderLine/alphaSkia", "files": [ "/lib/libalphaskianode-win-x64-node/libalphaskianode.node", "/lib/libalphaskianode-win-x86-node/libalphaskianode.node", diff --git a/lib/node/alphaskia/package.json b/lib/node/alphaskia/package.json index ce7b69d..e0c3aea 100644 --- a/lib/node/alphaskia/package.json +++ b/lib/node/alphaskia/package.json @@ -20,14 +20,17 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/CoderLine/alphaSkia.git" + "url": "https://github.com/CoderLine/alphaSkia.git", + "directory": "lib/node/alphaskia" + }, + "author": { + "name": "Daniel Kuschny" }, - "author": "Daniel Kuschny", "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/CoderLine/alphaSkia/issues" }, - "homepage": "https://github.com/CoderLine/alphaSkia#readme", + "homepage": "https://github.com/CoderLine/alphaSkia", "optionalDependencies": { "@coderline/alphaskia-linux": "^1.0.0", "@coderline/alphaskia-macos": "^1.0.0", diff --git a/lib/node/alphaskia/rollup.config.js b/lib/node/alphaskia/rollup.config.js index 5cb8162..a8eb1eb 100644 --- a/lib/node/alphaskia/rollup.config.js +++ b/lib/node/alphaskia/rollup.config.js @@ -20,7 +20,7 @@ module.exports = [ plugins: [terser()] } ].map(o => ({ ...commonOutput, ...o })), - external: [], + external: ['url', 'path', 'fs'], watch: { include: 'dist/lib/**', exclude: 'node_modules/**' @@ -34,6 +34,7 @@ module.exports = [ format: 'es' } ], + external: ['url', 'path', 'fs'], plugins: [ dts() ] diff --git a/lib/node/alphaskia/src/AlphaSkiaCanvas.ts b/lib/node/alphaskia/src/AlphaSkiaCanvas.ts index f46a8ab..6315ff4 100644 --- a/lib/node/alphaskia/src/AlphaSkiaCanvas.ts +++ b/lib/node/alphaskia/src/AlphaSkiaCanvas.ts @@ -3,9 +3,17 @@ import { AlphaSkiaNative } from './AlphaSkiaNative'; import { AlphaSkiaTypeface } from './AlphaSkiaTypeface'; import { AlphaSkiaTextBaseline, AlphaSkiaCanvasHandle, AlphaSkiaColorType, AlphaSkiaTextAlign, loadAddon } from './addon'; +/** + * A Skia based canvas for rendering images. + */ export class AlphaSkiaCanvas extends AlphaSkiaNative { static #colorType: AlphaSkiaColorType | undefined; + /** + * Gets the {@link AlphaSkiaColorType} used when generating images. + * AlphaSkia tries to use the native color tpe of the system but this can vary based on OS. + * @return The {@link AlphaSkiaColorType} used when generating images + */ public static get colorType(): AlphaSkiaColorType { if (!AlphaSkiaCanvas.#colorType) { AlphaSkiaCanvas.#colorType = loadAddon().alphaskia_get_color_type(); @@ -13,48 +21,96 @@ export class AlphaSkiaCanvas extends AlphaSkiaNative { return AlphaSkiaCanvas.#colorType; } + /** + * Gets the color to use for drawing operations in the native canvas. + * See also {@link rgbaToColor} + * @return The color to use for drawing operations in the native canvas + */ public get color(): number { this.checkDisposed(); return loadAddon().alphaskia_canvas_get_color(this.handle!); } + /** + * Sets the color to use for drawing operations in the native canvas. + * See also {@link rgbaToColor} + * @param color The color to use for drawing operations in the native canvas. + */ public set color(color: number) { this.checkDisposed(); loadAddon().alphaskia_canvas_set_color(this.handle!, color); } - public static rgbaToColor(r: number, g: number, b: number, a: number) { + /** + * Encodes the given color components into the right format. + * + * @param r The red component of the color. + * @param g The green component of the color. + * @param b The blue component of the color. + * @param a The alpha channel of the color. + * @return The encoded color. + */ + public static rgbaToColor(r: number, g: number, b: number, a: number): number { return ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0); } + /** + * Gets the line width to use when drawing strokes and lines. + * @return The line width to use when drawing strokes and lines. + */ public get lineWidth(): number { this.checkDisposed(); return loadAddon().alphaskia_canvas_get_line_width(this.handle!); } + /** + * Sets the line width to use when drawing strokes and lines. + * @param lineWidth The line width to use when drawing strokes and lines + */ public set lineWidth(lineWidth: number) { this.checkDisposed(); loadAddon().alphaskia_canvas_set_line_width(this.handle!, lineWidth); } /** - * @internal + * Initializes a new empty canvas to use for drawing. */ public constructor() { super(loadAddon().alphaskia_canvas_new()!, loadAddon().alphaskia_canvas_free); loadAddon().alphaskia_canvas_begin_render(this.handle!, 100, 100, 1); } + /** + * Starts a new rendering session in the canvas. + * + * @param width The width of the image to produce. + * @param height The height of the image to produce. + * @param scaleFactor The scale factor for the image (e.g. for high DPI rendering with keeping coordinates). + */ public beginRender(width: number, height: number, renderScale: number = 1): void { this.checkDisposed(); loadAddon().alphaskia_canvas_begin_render(this.handle!, width, height, renderScale); } + /** + * Draws the given image into the canvas. + * + * @param image The image to draw. + * @param x The X-coordinate at which to draw the image. + * @param y The Y-coordinate at which to draw the image. + * @param w The target width to which the image should be scaled. + * @param h The target height to which the image should be scaled. + */ public drawImage(image: AlphaSkiaImage, x: number, y: number, w: number, h: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_draw_image(this.handle!, image.handle!, x, y, w, h); } + /** + * Ends the rendering session and provides the rendered result. + * + * @return The rendered result or {@code null} if something went wrong. + */ public endRender(): AlphaSkiaImage | undefined { this.checkDisposed(); const image = loadAddon().alphaskia_canvas_end_render(this.handle!); @@ -64,81 +120,182 @@ export class AlphaSkiaCanvas extends AlphaSkiaNative { return new AlphaSkiaImage(image); } + /** + * Fills the given rectangle with the current color. + * + * @param x The X-coordinate of the rectangle + * @param y The Y-coordinate of the rectangle + * @param width The width of the rectangle + * @param height The height of the rectangle + */ public fillRect(x: number, y: number, width: number, height: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_fill_rect(this.handle!, x, y, width, height); } + /** + * Strokes the given rectangle with the current color. + * + * @param x The X-coordinate of the rectangle + * @param y The Y-coordinate of the rectangle + * @param width The width of the rectangle + * @param height The height of the rectangle + */ public strokeRect(x: number, y: number, width: number, height: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_stroke_rect(this.handle!, x, y, width, height); } + /** + * Begins a new dynamic path for rendering. + */ public beginPath(): void { this.checkDisposed(); loadAddon().alphaskia_canvas_begin_path(this.handle!); } + /** + * Closes the started path by connecting the last point and the first point. + */ public closePath(): void { this.checkDisposed(); loadAddon().alphaskia_canvas_close_path(this.handle!); } + /** + * Moves the current position within the current path to the given position. + * + * @param x The X-position where to continue the path. + * @param y The Y-position where to continue the path. + */ public moveTo(x: number, y: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_move_to(this.handle!, x, y); } + /** + * Draws a line from the current path position to the given position. + * + * @param x The X-position to which to draw a line. + * @param y The Y-position to which to draw a line. + */ public lineTo(x: number, y: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_line_to(this.handle!, x, y); } + /** + * Draws a quadratic curve from the current path position to the given position. + * + * @param cpx The X-position of the control point. + * @param cpy The Y-position of the control point. + * @param x The X-position of the curve end. + * @param y The Y-position of the curve end. + */ public quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_quadratic_curve_to(this.handle!, cpx, cpy, x, y); } + /** + * Draws a Bézier curve from the current path position to the given position. + * + * @param cp1X The X-position of the first control point. + * @param cp1Y The Y-position of the first control point. + * @param cp2X The X-position of the second control point. + * @param cp2Y The Y-position of the second control point. + * @param x The X-position of the curve end. + * @param y The Y-position of the curve end. + */ public bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_bezier_curve_to(this.handle!, cp1x, cp1y, cp2x, cp2y, x, y); } + /** + * Fills a circle with the current color. + * + * @param x The X-position of the circle center. + * @param y The Y-position of the circle center. + * @param radius The circle radius. + */ public fillCircle(x: number, y: number, radius: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_fill_circle(this.handle!, x, y, radius); } + /** + * Strokes a circle with the current color and line width. + * + * @param x The X-position of the circle center. + * @param y The Y-position of the circle center. + * @param radius The circle radius. + */ public strokeCircle(x: number, y: number, radius: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_stroke_circle(this.handle!, x, y, radius); } + /** + * Fills the current path with the current color. + */ public fill(): void { this.checkDisposed(); loadAddon().alphaskia_canvas_fill(this.handle!); } + /** + * Strokes the current path with the current color and line width. + */ public stroke(): void { this.checkDisposed(); loadAddon().alphaskia_canvas_stroke(this.handle!); } + /** + * Fills a text with the current color and provided details. + * + * @param text The text to draw. + * @param typeface The typeface to use for drawing the text. + * @param fontSize The font size to use when drawing the text. + * @param x The X-position where to draw the text to. + * @param y The Y-position where to draw the text to. + * @param textAlign How to align the text at the given position horizontally. + * @param baseline How to align the text at the given position vertically. + */ public fillText(text: string, typeface: AlphaSkiaTypeface, fontSize: number, x: number, y: number, textAlign: AlphaSkiaTextAlign, baseline: AlphaSkiaTextBaseline): void { this.checkDisposed(); loadAddon().alphaskia_canvas_fill_text(this.handle!, text, typeface.handle!, fontSize, x, y, textAlign as number, baseline as number); } + /** + * Measures the given text. + * + * @param text The text to measure. + * @param typeface The typeface to use for drawing the text. + * @param fontSize The font size to use when drawing the text. + * @return The horizontal width of the text when it would be drawn. + */ public measureText(text: string, typeface: AlphaSkiaTypeface, fontSize: number): number { this.checkDisposed(); return loadAddon().alphaskia_canvas_measure_text(this.handle!, text, typeface.handle!, fontSize); } + /** + * Rotates the canvas allowing angled drawing. . + * + * @param centerX The X-position of the center around which to rotate. + * @param centerY The Y-position of the center around which to rotate. + * @param angle The angle in degrees to rotate. + */ public beginRotate(centerX: number, centerY: number, angle: number): void { this.checkDisposed(); loadAddon().alphaskia_canvas_begin_rotate(this.handle!, centerX, centerY, angle); } + /** + * Restores the previous rotation state after {@link #beginRotate} was called. + */ public endRotate(): void { this.checkDisposed(); loadAddon().alphaskia_canvas_end_rotate(this.handle!); diff --git a/lib/node/alphaskia/src/AlphaSkiaData.ts b/lib/node/alphaskia/src/AlphaSkiaData.ts index cab0201..cfd380a 100644 --- a/lib/node/alphaskia/src/AlphaSkiaData.ts +++ b/lib/node/alphaskia/src/AlphaSkiaData.ts @@ -1,10 +1,10 @@ import { AlphaSkiaNative } from './AlphaSkiaNative'; import { AlphaSkiaDataHandle, loadAddon } from './addon'; +/** + * @internal + */ export class AlphaSkiaData extends AlphaSkiaNative { - /** - * @internal - */ public constructor(handle: AlphaSkiaDataHandle) { super(handle, loadAddon().alphaskia_data_free); } diff --git a/lib/node/alphaskia/src/AlphaSkiaImage.ts b/lib/node/alphaskia/src/AlphaSkiaImage.ts index 8776871..83ca2e6 100644 --- a/lib/node/alphaskia/src/AlphaSkiaImage.ts +++ b/lib/node/alphaskia/src/AlphaSkiaImage.ts @@ -1,12 +1,25 @@ import { AlphaSkiaNative } from './AlphaSkiaNative'; import { AlphaSkiaImageHandle, loadAddon } from './addon'; +/** + * Represents a final rendered image. + */ export class AlphaSkiaImage extends AlphaSkiaNative { + /** + * Gets the width of the image. + * + * @return the width of the image + */ public get width(): number { this.checkDisposed(); return loadAddon().alphaskia_image_get_width(this.handle!); } + /** + * Gets the height of the image. + * + * @return the height of the image + */ public get height(): number { this.checkDisposed(); return loadAddon().alphaskia_image_get_height(this.handle!); @@ -19,11 +32,21 @@ export class AlphaSkiaImage extends AlphaSkiaNative { super(handle, loadAddon().alphaskia_image_free); } + /** + * Reads the raw pixel data of this image as byte array. + * + * @return A copy of the raw pixel data. + */ public readPixels(): ArrayBuffer | undefined { this.checkDisposed(); return loadAddon().alphaskia_image_read_pixels(this.handle!); } + /** + * Encodes the image to a PNG. + * + * @return The raw PNG bytes for further usage. + */ public toPng(): ArrayBuffer | undefined { this.checkDisposed(); return loadAddon().alphaskia_image_encode_png(this.handle!); diff --git a/lib/node/alphaskia/src/AlphaSkiaNative.ts b/lib/node/alphaskia/src/AlphaSkiaNative.ts index 5432481..e252d8a 100644 --- a/lib/node/alphaskia/src/AlphaSkiaNative.ts +++ b/lib/node/alphaskia/src/AlphaSkiaNative.ts @@ -1,3 +1,6 @@ +/** + * The base class for AlphaSkia objects wrapping native Skia objects. + */ export class AlphaSkiaNative implements Disposable { #release: (handle: THandle) => void; #handle: THandle | undefined; @@ -17,6 +20,10 @@ export class AlphaSkiaNative implements Disposable { this.#release = release; } + /** + * Checks whether the object has already been disposed and throws an exception if so. + * @throws {@link ReferenceError} Thrown if this instance was already disposed. + */ protected checkDisposed() { if (!this.#handle) { throw new ReferenceError("Object was already disposed"); diff --git a/lib/node/alphaskia/src/AlphaSkiaPlatform.ts b/lib/node/alphaskia/src/AlphaSkiaPlatform.ts index 275d2b9..05d4d99 100644 --- a/lib/node/alphaskia/src/AlphaSkiaPlatform.ts +++ b/lib/node/alphaskia/src/AlphaSkiaPlatform.ts @@ -23,10 +23,24 @@ if (nodeModulesIndex > 0) { searchPaths.push(path.join(__dirname.substring(0, nodeModulesIndex), 'node_modules', '@coderline', `alphaskia-${platform}`, 'lib')) } +/** + * Adds custom search paths which should be considered when loading the native addon of alphaSkia. + * @param paths The paths to add. + */ export function addSearchPaths(...paths: string[]) { searchPaths.push(...paths); } +/** + * Attempts to resolve the native node addon for alphaSkia which is typically placed in an operating system platform + * and architecture specific folder starting from certain search paths. + * + * By default the following paths are considered + * * /lib + * * /lib + * * node_modules/@coderline/alphaskia-/lib (if we detect that the alphaSkia script file is below node_modules). + * @returns The resolved path to the native node addon to load for this platform or undefined if it could not be found. + */ export function findAddonPath(): string | undefined { const libDirectory = `libalphaskianode-${platform}-${arch}-node`; for (const searchPath of searchPaths) { diff --git a/lib/node/alphaskia/src/AlphaSkiaTypeface.ts b/lib/node/alphaskia/src/AlphaSkiaTypeface.ts index 6c68999..454a5ab 100644 --- a/lib/node/alphaskia/src/AlphaSkiaTypeface.ts +++ b/lib/node/alphaskia/src/AlphaSkiaTypeface.ts @@ -2,13 +2,16 @@ import { AlphaSkiaData } from './AlphaSkiaData'; import { AlphaSkiaNative } from './AlphaSkiaNative'; import { AlphaSkiaTypefaceHandle, loadAddon } from './addon'; +/** + * Represents a typeface to draw text. + */ export class AlphaSkiaTypeface extends AlphaSkiaNative { #data: AlphaSkiaData | undefined; /** * @internal */ - public constructor(handle: AlphaSkiaTypefaceHandle, data?: AlphaSkiaData) { + private constructor(handle: AlphaSkiaTypefaceHandle, data?: AlphaSkiaData) { super(handle, loadAddon().alphaskia_typeface_free); this.#data = data; } @@ -21,11 +24,11 @@ export class AlphaSkiaTypeface extends AlphaSkiaNative } } - public toArray(): ArrayBuffer { - this.checkDisposed(); - return loadAddon().alphaskia_data_get_data(this.handle!); - } - + /** + * Register a new custom font from the given binary data containing the data of a font compatible with Skia (e.g. TTF). + * @param data The raw binary data of the font. + * @return The loaded typeface to use for text rendering or {@code null} if the loading failed. + */ public static register(data: ArrayBuffer): AlphaSkiaTypeface | undefined { const nativeData = loadAddon().alphaskia_data_new_copy(data); if (!nativeData) { @@ -40,6 +43,13 @@ export class AlphaSkiaTypeface extends AlphaSkiaNative return new AlphaSkiaTypeface(typeface, new AlphaSkiaData(nativeData)); } + /** + * Creates a typeface using the provided information. + * @param name The name of the typeface. + * @param bold Whether the bold version of the typeface should be loaded. + * @param italic Whether the italic version of the typeface should be loaded. + * @return The typeface if it can be found in the already loaded fonts or the system fonts, otherwise {@code null}. + */ public static create(name: string, bold: boolean, italic: boolean): AlphaSkiaTypeface | undefined { const typeface = loadAddon().alphaskia_typeface_make_from_name(name, bold, italic); if (!typeface) { diff --git a/lib/node/alphaskia/src/addon.ts b/lib/node/alphaskia/src/addon.ts index f374e4e..ca630e8 100644 --- a/lib/node/alphaskia/src/addon.ts +++ b/lib/node/alphaskia/src/addon.ts @@ -7,16 +7,43 @@ export interface AlphaSkiaTypefaceHandle { } export interface AlphaSkiaImageHandle { } export interface AlphaSkiaCanvasHandle { } +/** + * Lists all text alignments which can be used to draw text. + */ export enum AlphaSkiaTextAlign { + /** + * The text is drawn left aligned to the provided position. + */ Left = 0, + /** + * The text is drawn centered to the provided position. + */ Center = 1, + /** + * The text is drawn right aligned to the provided position. + */ Right = 2 } +/** + * Lists all vertical text baseline alignments which can be used to draw text. + */ export enum AlphaSkiaTextBaseline { + /** + * The text is drawn using the alphabetic baseline. + */ Alphabetic = 0, + /** + * The text is top-aligned to the provided position. + */ Top = 1, + /** + * The test is middle-aligned (vertically centered) to the provided position. + */ Middle = 2, + /** + * The text is bottom-aligned to the provided position. + */ Bottom = 3 } @@ -38,6 +65,9 @@ export enum AlphaSkiaColorType { Bgra888 = 6 } +/** + * @internal + */ export interface AlphaSkiaNodeAddon { alphaskia_get_color_type(): AlphaSkiaColorType; @@ -87,7 +117,11 @@ export interface AlphaSkiaNodeAddon { } const require = createRequire(import.meta.url); -let addonInstance: AlphaSkiaNodeAddon | undefined = undefined; +let addonInstance: AlphaSkiaNodeAddon | undefined = undefined + +/** + * @internal + */ export function loadAddon() { if (!addonInstance) { const addonPath = findAddonPath(); diff --git a/wrapper/src/alphaskia.rc b/wrapper/src/alphaskia.rc new file mode 100644 index 0000000..6fc475e --- /dev/null +++ b/wrapper/src/alphaskia.rc @@ -0,0 +1,57 @@ +#include +#include +#include "../include/generated/version_info.h" + +// https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource + +#ifdef RC_INVOKED + +#ifndef DEBUG + #define VER_FF_DEBUG 0 +#else + #define VER_FF_DEBUG VS_FF_DEBUG +#endif + +#ifdef IS_LOCAL_BUILD + #define VER_FF_RELEASE (VS_FF_PRIVATEBUILD|VS_FF_PRERELEASE) +#else + #ifdef IS_RELEASE_BUILD + #define VER_FF_RELEASE 0 + #else + #define VER_FF_RELEASE VS_FF_PRERELEASE + #endif +#endif + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS (VER_FF_RELEASE|VER_FF_DEBUG) +FILEOS VOS__WINDOWS32 +FILETYPE VFT_DLL +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", VER_COMPANY_STR + VALUE "FileDescription", VER_FILE_DESCRIPTION_STR + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", VER_INTERNALNAME_STR + VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "LegalTrademarks1", VER_LEGALTRADEMARKS1_STR + VALUE "LegalTrademarks2", VER_LEGALTRADEMARKS2_STR + VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR + VALUE "ProductName", VER_PRODUCTNAME_STR + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif From 3c0cb1136a12ca0a9bc426d8d6f6c9c66a398325 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sat, 14 Oct 2023 16:29:23 +0200 Subject: [PATCH 2/5] Add version number --- .github/workflows/build.yml | 4 +++- build/Build.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c97bc4d..644d0d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,8 +6,10 @@ on: description: Use Skia Binary from cache default: false -jobs: +env: + ALPHASKIA_VERSION: 1.0.0.${{ github.run_number }} +jobs: # # Windows windows-skia: diff --git a/build/Build.cs b/build/Build.cs index 9a9a67c..ec7a221 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -9,7 +9,7 @@ static class VersionInfo { public const string Company = "CoderLine"; public const string Description = "A Skia based rendering backend for alphaTab."; - public static readonly Version FileVersion = GetVariable("VERSION") ?? new Version(1, 0, 0, 0); + public static readonly Version FileVersion = GetVariable("ALPHASKIA_VERSION") ?? new Version(1, 0, 0, 0); public static readonly string Copyright = $"Copyright © {DateTime.Now.Year}, Daniel Kuschny"; public const string AuthorId = "danielku15"; public const string AuthorName = "Daniel Kuschny"; From 5993342f25e4094971d752cbc5d39888d3dcb3d3 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sat, 14 Oct 2023 16:59:09 +0200 Subject: [PATCH 3/5] Add 'node:module' to externals --- lib/node/alphaskia/rollup.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node/alphaskia/rollup.config.js b/lib/node/alphaskia/rollup.config.js index a8eb1eb..0b4197f 100644 --- a/lib/node/alphaskia/rollup.config.js +++ b/lib/node/alphaskia/rollup.config.js @@ -20,7 +20,7 @@ module.exports = [ plugins: [terser()] } ].map(o => ({ ...commonOutput, ...o })), - external: ['url', 'path', 'fs'], + external: ['url', 'path', 'fs', 'node:module'], watch: { include: 'dist/lib/**', exclude: 'node_modules/**' @@ -34,7 +34,7 @@ module.exports = [ format: 'es' } ], - external: ['url', 'path', 'fs'], + external: ['url', 'path', 'fs', 'node:module'], plugins: [ dts() ] From 381b48eeb33d6ed7e18f7cca6b5e60f7d187ce53 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sat, 14 Oct 2023 17:05:22 +0200 Subject: [PATCH 4/5] Call publish task on java --- build/Build.Java.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Build.Java.cs b/build/Build.Java.cs index 2c2f2dc..5e1720d 100644 --- a/build/Build.Java.cs +++ b/build/Build.Java.cs @@ -20,7 +20,7 @@ partial class Build .DependsOn(JavaBuild) .Executes(() => { - GradlewTool("assemble", + GradlewTool("publishAllPublicationsToDistPathRepository", workingDirectory: RootDirectory / "lib" / "java"); }); From 59c0e91f061038e41ae998d45ce1d9ed9fccd053 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sat, 14 Oct 2023 17:22:03 +0200 Subject: [PATCH 5/5] Corrected java packaging path --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 644d0d7..41613c2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -220,7 +220,7 @@ jobs: with: name: Maven path: | - lib/dist/**/*.* + lib/java/dist/**/*.* node: runs-on: ubuntu-latest