diff --git a/binding/IncludeNativeAssets.SkiaSharp.WinUI.targets b/binding/IncludeNativeAssets.SkiaSharp.WinUI.targets new file mode 100644 index 0000000000..89e4c652b7 --- /dev/null +++ b/binding/IncludeNativeAssets.SkiaSharp.WinUI.targets @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/binding/SkiaSharp.NativeAssets.WinUI/SkiaSharp.NativeAssets.WinUI.csproj b/binding/SkiaSharp.NativeAssets.WinUI/SkiaSharp.NativeAssets.WinUI.csproj new file mode 100644 index 0000000000..07bac2c33b --- /dev/null +++ b/binding/SkiaSharp.NativeAssets.WinUI/SkiaSharp.NativeAssets.WinUI.csproj @@ -0,0 +1,16 @@ + + + $(WindowsTargetFrameworks) + SkiaSharp + $(PackagingGroup) - Native Assets for Windows UI (WinUI 3) + true + + + + + + + + + + \ No newline at end of file diff --git a/build.cake b/build.cake index 2812886d6d..6d36c029bf 100644 --- a/build.cake +++ b/build.cake @@ -101,6 +101,7 @@ var TRACKED_NUGETS = new Dictionary { { "SkiaSharp.NativeAssets.Tizen", new Version (1, 60, 0) }, { "SkiaSharp.NativeAssets.tvOS", new Version (1, 60, 0) }, { "SkiaSharp.NativeAssets.Win32", new Version (1, 60, 0) }, + { "SkiaSharp.NativeAssets.WinUI", new Version (1, 60, 0) }, { "SkiaSharp.Views", new Version (1, 60, 0) }, { "SkiaSharp.Views.Desktop.Common", new Version (1, 60, 0) }, { "SkiaSharp.Views.Gtk3", new Version (1, 60, 0) }, diff --git a/externals/.gitignore b/externals/.gitignore index df5b644fa9..d83a461853 100644 --- a/externals/.gitignore +++ b/externals/.gitignore @@ -1,3 +1,4 @@ angle/ package_cache/ vcpkg/ +winappsdk/ diff --git a/native/.gitignore b/native/.gitignore index 2a4fe393c9..2f11c1ce72 100644 --- a/native/.gitignore +++ b/native/.gitignore @@ -1,3 +1,4 @@ xcuserdata/ project.xcworkspace/ uwp/ANGLE/triplets +Generated Files/ diff --git a/native/winui/ANGLE.cake b/native/winui/ANGLE.cake new file mode 100644 index 0000000000..88c33903e6 --- /dev/null +++ b/native/winui/ANGLE.cake @@ -0,0 +1,75 @@ +void InitializeAngle(string branch, DirectoryPath ANGLE_PATH, DirectoryPath WINAPPSDK_PATH) +{ + if (!DirectoryExists(ANGLE_PATH)) { + RunProcess("git", $"clone https://github.com/google/angle.git --branch {branch} --depth 1 --single-branch --shallow-submodules {ANGLE_PATH}"); + } + + var submodules = new[] { + "build", + "testing", + "third_party/zlib", + "third_party/jsoncpp", + "third_party/vulkan-deps", + "third_party/astc-encoder/src", + "tools/clang", + }; + foreach (var submodule in submodules) { + var sub = ANGLE_PATH.Combine(submodule); + if (FileExists(sub.CombineWithFilePath("BUILD.gn")) || FileExists(sub.CombineWithFilePath(".gitignore"))) + continue; + + RunProcess("git", new ProcessSettings { + Arguments = $"submodule update --init --recursive {submodule}", + WorkingDirectory = ANGLE_PATH.FullPath, + }); + } + + { + var toolchain = ANGLE_PATH.CombineWithFilePath("build/toolchain/win/toolchain.gni"); + var contents = System.IO.File.ReadAllText(toolchain.FullPath); + var newContents = contents + .Replace("\"${dllname}.lib\"", "\"{{output_dir}}/{{target_output_name}}.lib\"") + .Replace("\"${dllname}.pdb\"", "\"{{output_dir}}/{{target_output_name}}.pdb\""); + if (contents != newContents) + System.IO.File.WriteAllText(toolchain.FullPath, newContents); + } + + if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/config/gclient_args.gni"))) { + var lines = new[] { + "checkout_angle_internal = false", + "checkout_angle_mesa = false", + "checkout_angle_restricted_traces = false", + "generate_location_tags = false" + }; + System.IO.File.WriteAllLines(ANGLE_PATH.CombineWithFilePath("build/config/gclient_args.gni").FullPath, lines); + } + + if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/util/LASTCHANGE"))) { + var lastchange = ANGLE_PATH.CombineWithFilePath("build/util/LASTCHANGE"); + RunPython(ANGLE_PATH, ANGLE_PATH.CombineWithFilePath("build/util/lastchange.py"), $"-o {lastchange}"); + } + + if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/toolchain/win/rc/win/rc.exe"))) { + var oldPath = EnvironmentVariable("PATH"); + try { + System.Environment.SetEnvironmentVariable("PATH", DEPOT_PATH.FullPath + System.IO.Path.PathSeparator + oldPath); + + RunPython(ANGLE_PATH, + DEPOT_PATH.CombineWithFilePath("download_from_google_storage.py"), + $"--no_resume --no_auth --bucket chromium-browser-clang/rc -s build/toolchain/win/rc/win/rc.exe.sha1"); + } finally { + System.Environment.SetEnvironmentVariable("PATH", oldPath); + } + } + + if (!FileExists(ANGLE_PATH.CombineWithFilePath("third_party/llvm-build/Release+Asserts/cr_build_revision"))) { + RunPython(ANGLE_PATH, ANGLE_PATH.CombineWithFilePath("tools/clang/scripts/update.py")); + } + + if (!FileExists(WINAPPSDK_PATH.CombineWithFilePath("Microsoft.WindowsAppSDK.nuspec"))) { + var setup = ANGLE_PATH.CombineWithFilePath("scripts/winappsdk_setup.py"); + RunProcess( + ROOT_PATH.CombineWithFilePath("scripts/vcvarsall.bat"), + $"\"{VS_INSTALL}\" \"x64\" \"{PYTHON_EXE}\" \"{setup}\" --output \"{WINAPPSDK_PATH}\""); + } +} diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.props b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.props new file mode 100644 index 0000000000..67ea2536c9 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.props @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.targets b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.targets new file mode 100644 index 0000000000..3d8b24a04d --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.targets @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/SkiaSharp.Views.WinUI.Native.Projection.csproj b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/SkiaSharp.Views.WinUI.Native.Projection.csproj new file mode 100644 index 0000000000..85615cef2f --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/SkiaSharp.Views.WinUI.Native.Projection.csproj @@ -0,0 +1,26 @@ + + + + net7.0-windows10.0.19041.0 + 10.0.17763.0 + SkiaSharp.Views.WinUI + SkiaSharp.Views.WinUI + false + enable + enable + + + + None + SkiaSharp.Views.WinUI.Native + + + + + + + + + + + diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln new file mode 100644 index 0000000000..0435478c90 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln @@ -0,0 +1,61 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34310.174 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SkiaSharp.Views.WinUI.Native", "SkiaSharp.Views.WinUI.Native\SkiaSharp.Views.WinUI.Native.vcxproj", "{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.WinUI.Native.Projection", "SkiaSharp.Views.WinUI.Native.Projection\SkiaSharp.Views.WinUI.Native.Projection.csproj", "{95E9FEB4-DCD3-4514-8208-A87688788BB2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|Any CPU.ActiveCfg = Debug|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|Any CPU.Build.0 = Debug|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|ARM64.Build.0 = Debug|ARM64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x64.ActiveCfg = Debug|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x64.Build.0 = Debug|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x86.ActiveCfg = Debug|Win32 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x86.Build.0 = Debug|Win32 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|Any CPU.ActiveCfg = Release|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|Any CPU.Build.0 = Release|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|ARM64.ActiveCfg = Release|ARM64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|ARM64.Build.0 = Release|ARM64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x64.ActiveCfg = Release|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x64.Build.0 = Release|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x86.ActiveCfg = Release|Win32 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x86.Build.0 = Release|Win32 + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|ARM64.Build.0 = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x64.ActiveCfg = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x64.Build.0 = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x86.ActiveCfg = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x86.Build.0 = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|Any CPU.Build.0 = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|ARM64.ActiveCfg = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|ARM64.Build.0 = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x64.ActiveCfg = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x64.Build.0 = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x86.ActiveCfg = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FB8DA12F-84B5-4D7F-A6E1-7F0A53AA4535} + EndGlobalSection +EndGlobal diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.cpp b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.cpp new file mode 100644 index 0000000000..c2174e6cf7 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.cpp @@ -0,0 +1,19 @@ +#include "pch.h" +#include "PropertySetExtensions.h" +#include "PropertySetExtensions.g.cpp" + +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Foundation::Collections; + +namespace winrt::SkiaSharp::Views::WinUI::Native::implementation +{ + void PropertySetExtensions::AddSingle(PropertySet const& propertySet, hstring const& key, float value) + { + propertySet.Insert(key, PropertyValue::CreateSingle(value)); + } + + void PropertySetExtensions::AddSize(PropertySet const& propertySet, hstring const& key, Size const& height) + { + propertySet.Insert(key, PropertyValue::CreateSize(height)); + } +} diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.h b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.h new file mode 100644 index 0000000000..de60e32b45 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.h @@ -0,0 +1,24 @@ +#pragma once + +#include "PropertySetExtensions.g.h" + +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Foundation::Collections; + +namespace winrt::SkiaSharp::Views::WinUI::Native::implementation +{ + struct PropertySetExtensions + { + PropertySetExtensions() = default; + + static void AddSingle(PropertySet const& propertySet, hstring const& key, float value); + static void AddSize(PropertySet const& propertySet, hstring const& key, Size const& value); + }; +} + +namespace winrt::SkiaSharp::Views::WinUI::Native::factory_implementation +{ + struct PropertySetExtensions : PropertySetExtensionsT + { + }; +} diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.idl b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.idl new file mode 100644 index 0000000000..278b3c896c --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.idl @@ -0,0 +1,8 @@ +namespace SkiaSharp.Views.WinUI.Native +{ + static runtimeclass PropertySetExtensions + { + static void AddSingle(Windows.Foundation.Collections.PropertySet propertySet, String key, Single value); + static void AddSize(Windows.Foundation.Collections.PropertySet propertySet, String key, Windows.Foundation.Size value); + } +} diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj new file mode 100644 index 0000000000..44c4f7dfda --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj @@ -0,0 +1,183 @@ + + + + + + + true + true + true + {730af4c9-82d2-4fa7-aa32-154f3524ebd2} + SkiaSharp.Views.WinUI.Native + SkiaSharp.Views.WinUI.Native + en-US + 16.0 + false + Windows Store + 10.0 + 10.0.22621.0 + 10.0.17763.0 + true + true + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + DynamicLibrary + v143 + Unicode + false + true + + + true + true + + + false + true + false + + + + + + + + + + + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + _WINRT_DLL;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + true + SkiaSharp_Views_WinUI_Native.def + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + PropertySetExtensions.cpp + + + + + Create + + + + + + + Code + PropertySetExtensions.cpp + + + + + + + + + false + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj.filters b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj.filters new file mode 100644 index 0000000000..099f47d334 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + accd3aa8-1ba0-4223-9bbe-0c431709210b + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {926ab91d-31b4-48c3-b9a4-e681349f27f0} + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp_Views_WinUI_Native.def b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp_Views_WinUI_Native.def new file mode 100644 index 0000000000..24e7c1235c --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp_Views_WinUI_Native.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/packages.config b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/packages.config new file mode 100644 index 0000000000..152b1d8ec4 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.cpp b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.cpp new file mode 100644 index 0000000000..1d9f38c57d --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.h b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.h new file mode 100644 index 0000000000..1533d96bb2 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include +#include +#include + +// Undefine GetCurrentTime macro to prevent +// conflict with Storyboard::GetCurrentTime +#undef GetCurrentTime + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/readme.txt b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/readme.txt new file mode 100644 index 0000000000..fd4c59a522 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/readme.txt @@ -0,0 +1,27 @@ +======================================================================== + SkiaSharp.Views.WinUI.Native Project Overview +======================================================================== + +This project demonstrates how to get started authoring Windows Runtime +classes directly with standard C++, using the Windows App SDK and +C++/WinRT packages to generate implementation headers from interface +(IDL) files. The generated Windows Runtime component binary and WinMD +files should then be bundled with the app consuming them. + +Steps: +1. Create an interface (IDL) file to define your Windows Runtime class, + its default interface, and any other interfaces it implements. +2. Build the project once to generate module.g.cpp, module.h.cpp, and + implementation templates under the "Generated Files" folder, as + well as skeleton class definitions under "Generated Files\sources". +3. Use the skeleton class definitions for reference to implement your + Windows Runtime classes. + +======================================================================== +Learn more about Windows App SDK here: +https://docs.microsoft.com/windows/apps/windows-app-sdk/ +Learn more about WinUI3 here: +https://docs.microsoft.com/windows/apps/winui/winui3/ +Learn more about C++/WinRT here: +http://aka.ms/cppwinrt/ +======================================================================== diff --git a/native/winui/build.cake b/native/winui/build.cake new file mode 100644 index 0000000000..7409df544f --- /dev/null +++ b/native/winui/build.cake @@ -0,0 +1,93 @@ +DirectoryPath ROOT_PATH = MakeAbsolute(Directory("../..")); +DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native/winui")); + +#load "../../scripts/cake/native-shared.cake" +#load "../../scripts/cake/msbuild.cake" + +#load "ANGLE.cake" + +Task("ANGLE") + .IsDependentOn("git-sync-deps") + .WithCriteria(IsRunningOnWindows()) + .Does(() => +{ + var ANGLE_PATH = ROOT_PATH.Combine("externals/angle"); + var WINAPPSDK_PATH = ROOT_PATH.Combine("externals/winappsdk"); + + var branch = GetVersion("ANGLE", "release"); + + InitializeAngle(branch, ANGLE_PATH, WINAPPSDK_PATH); + + Build("x86"); + Build("x64"); + Build("arm64"); + + void Build(string arch) + { + if (Skip(arch)) return; + + try { + System.Environment.SetEnvironmentVariable("DEPOT_TOOLS_WIN_TOOLCHAIN", "0"); + + RunGn(ANGLE_PATH, $"out/winui/{arch}", + $"target_cpu='{arch}' " + + $"is_component_build=false " + + $"is_debug=false " + + $"is_clang=false " + + $"angle_is_winappsdk=true " + + $"winappsdk_dir='{WINAPPSDK_PATH}' " + + $"enable_precompiled_headers=false " + + $"angle_enable_null=false " + + $"angle_enable_wgpu=false " + + $"angle_enable_gl_desktop_backend=false " + + $"angle_enable_vulkan=false"); + + RunNinja(ANGLE_PATH, $"out/winui/{arch}", "libEGL libGLESv2"); + } finally { + System.Environment.SetEnvironmentVariable("DEPOT_TOOLS_WIN_TOOLCHAIN", ""); + } + + var outDir = OUTPUT_PATH.Combine(arch); + EnsureDirectoryExists(outDir); + CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui/{arch}/libEGL.dll"), outDir); + CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui/{arch}/libEGL.pdb"), outDir); + CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui/{arch}/libGLESv2.dll"), outDir); + CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui/{arch}/libGLESv2.pdb"), outDir); + } +}); + +Task("SkiaSharp.Views.WinUI.Native") + .WithCriteria(IsRunningOnWindows()) + .Does(() => +{ + Build("x86", "Win32"); + Build("x64", "x64"); + Build("arm64", "arm64"); + + void Build(string arch, string nativeArch) + { + if (Skip(arch)) return; + + RunProcess("nuget", "restore SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln"); + RunMSBuild("SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln", arch); + + var name = "SkiaSharp.Views.WinUI.Native"; + + var outDir = OUTPUT_PATH.Combine(arch); + EnsureDirectoryExists(outDir); + CopyFileToDirectory($"{name}/{name}/bin/{nativeArch}/{CONFIGURATION}/{name}.dll", outDir); + CopyFileToDirectory($"{name}/{name}/bin/{nativeArch}/{CONFIGURATION}/{name}.pdb", outDir); + CopyFileToDirectory($"{name}/{name}/bin/{nativeArch}/{CONFIGURATION}/{name}.winmd", outDir); + + var anyOutDir = OUTPUT_PATH.Combine("any"); + EnsureDirectoryExists(anyOutDir); + CopyFileToDirectory($"{name}/{name}.Projection/bin/{CONFIGURATION}/net7.0-windows10.0.19041.0/{name}.Projection.dll", anyOutDir); + CopyFileToDirectory($"{name}/{name}.Projection/bin/{CONFIGURATION}/net7.0-windows10.0.19041.0/{name}.Projection.pdb", anyOutDir); + } +}); + +Task("Default") + .IsDependentOn("ANGLE") + .IsDependentOn("SkiaSharp.Views.WinUI.Native"); + +RunTarget(TARGET); diff --git a/samples/Basic/WinUI/SkiaSharpSample/SkiaSharpSample.csproj b/samples/Basic/WinUI/SkiaSharpSample/SkiaSharpSample.csproj index c46e450c1e..40fc8e00b0 100644 --- a/samples/Basic/WinUI/SkiaSharpSample/SkiaSharpSample.csproj +++ b/samples/Basic/WinUI/SkiaSharpSample/SkiaSharpSample.csproj @@ -12,7 +12,7 @@ - + @@ -32,5 +32,6 @@ + diff --git a/scripts/VERSIONS.txt b/scripts/VERSIONS.txt index a7c9249bfa..234b8e0f5a 100644 --- a/scripts/VERSIONS.txt +++ b/scripts/VERSIONS.txt @@ -17,6 +17,7 @@ Microsoft.WindowsAppSDK release 1.3.230602002 Microsoft.Maui.Graphics release 7.0.92 Microsoft.Windows.SDK.NET.Ref release 10.0.19041.27 Microsoft.AspNetCore.Components.Web release 6.0.0 +ANGLE release chromium/6275 # native milestones # this is related to the API versions, not the library versions @@ -53,6 +54,7 @@ SkiaSharp.NativeAssets.macOS nuget 3.0.0 SkiaSharp.NativeAssets.Tizen nuget 3.0.0 SkiaSharp.NativeAssets.tvOS nuget 3.0.0 SkiaSharp.NativeAssets.Win32 nuget 3.0.0 +SkiaSharp.NativeAssets.WinUI nuget 3.0.0 SkiaSharp.Views nuget 3.0.0 SkiaSharp.Views.Desktop.Common nuget 3.0.0 SkiaSharp.Views.Gtk3 nuget 3.0.0 diff --git a/scripts/azure-templates-stages.yml b/scripts/azure-templates-stages.yml index 3095f48a26..9e36d4430f 100644 --- a/scripts/azure-templates-stages.yml +++ b/scripts/azure-templates-stages.yml @@ -128,6 +128,36 @@ stages: target: externals-windows additionalArgs: --buildarch=arm64 artifactName: native + - template: azure-templates-bootstrapper.yml # Build Native WinUI|x86 (Win) + parameters: + name: native_winui_x86_windows + displayName: WinUI x86 + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + target: externals-winui + additionalArgs: --buildarch=x86 + artifactName: native + - template: azure-templates-bootstrapper.yml # Build Native WinUI|x64 (Win) + parameters: + name: native_winui_x64_windows + displayName: WinUI x64 + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + target: externals-winui + additionalArgs: --buildarch=x64 + artifactName: native + - template: azure-templates-bootstrapper.yml # Build Native WinUI|arm64 (Win) + parameters: + name: native_winui_arm64_windows + displayName: WinUI arm64 + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + target: externals-winui + additionalArgs: --buildarch=arm64 + artifactName: native - template: azure-templates-bootstrapper.yml # Build Native NanoServer|x64 (Win) parameters: name: native_win32_x64_nanoserver_windows diff --git a/scripts/cake/native-shared.cake b/scripts/cake/native-shared.cake index 17ea4f05e6..8c3703e3e5 100644 --- a/scripts/cake/native-shared.cake +++ b/scripts/cake/native-shared.cake @@ -38,23 +38,43 @@ Task("git-sync-deps") if (actualIncrement != expectedIncrement) throw new Exception($"The libSkiaSharp C API version did not match the expected '{expectedIncrement}', instead was '{actualIncrement}'."); - RunProcess(PYTHON_EXE, new ProcessSettings { - Arguments = SKIA_PATH.CombineWithFilePath("tools/git-sync-deps").FullPath, - WorkingDirectory = SKIA_PATH.FullPath, - }); + RunPython(SKIA_PATH, SKIA_PATH.CombineWithFilePath("tools/git-sync-deps")); }); //////////////////////////////////////////////////////////////////////////////////////////////////// // HELPERS //////////////////////////////////////////////////////////////////////////////////////////////////// -void GnNinja(DirectoryPath outDir, string target, string skiaArgs) +void RunPython(DirectoryPath working, FilePath script, string args = "") +{ + RunProcess(PYTHON_EXE, new ProcessSettings { + Arguments = $"{script.FullPath} {args}", + WorkingDirectory = working.FullPath, + }); +} + +void RunGn(DirectoryPath working, DirectoryPath outDir, string args = "") { var isCore = Context.Environment.Runtime.IsCoreClr; var quote = IsRunningOnWindows() || isCore ? "\"" : "'"; var innerQuote = IsRunningOnWindows() || isCore ? "\\\"" : "\""; + RunProcess(GN_EXE, new ProcessSettings { + Arguments = $"gen {outDir} --script-executable={quote}{PYTHON_EXE}{quote} --args={quote}{args.Replace("'", innerQuote)}{quote}", + WorkingDirectory = working.FullPath, + }); +} + +void RunNinja(DirectoryPath working, DirectoryPath outDir, string target = "") +{ + var script = DEPOT_PATH.CombineWithFilePath("ninja.py"); + + RunPython(working, script, $"-C {outDir} {target}"); +} + +void GnNinja(DirectoryPath outDir, string target, string skiaArgs) +{ // override win_vc with the command line args if (!string.IsNullOrEmpty(VS_INSTALL)) { DirectoryPath win_vc = VS_INSTALL; @@ -67,16 +87,10 @@ void GnNinja(DirectoryPath outDir, string target, string skiaArgs) $" is_official_build={CONFIGURATION.ToLower() == "release"} ".ToLower(); // generate native skia build files - RunProcess(GN_EXE, new ProcessSettings { - Arguments = $"gen out/{outDir} --script-executable={quote}{PYTHON_EXE}{quote} --args={quote}{skiaArgs.Replace("'", innerQuote)}{quote}", - WorkingDirectory = SKIA_PATH.FullPath, - }); + RunGn(SKIA_PATH, $"out/{outDir}", skiaArgs); // build native skia - RunProcess(PYTHON_EXE, new ProcessSettings { - Arguments = DEPOT_PATH.CombineWithFilePath("ninja.py").FullPath + $" -C out/{outDir} {target}", - WorkingDirectory = SKIA_PATH.FullPath, - }); + RunNinja(SKIA_PATH, $"out/{outDir}", target); } bool Skip(string arch) diff --git a/scripts/get-build-type.ps1 b/scripts/get-build-type.ps1 index 0274f9008b..ba6ccdbb36 100644 --- a/scripts/get-build-type.ps1 +++ b/scripts/get-build-type.ps1 @@ -23,26 +23,30 @@ if ($intBuildId -gt 0) { if (("$ExternalsBuildId" -eq 'latest') -and ("$env:BUILD_REASON" -eq 'PullRequest')) { Write-Host "All changes:" $all = (git diff-tree --no-commit-id --name-only -r HEAD~ HEAD) - foreach ($d in $all) { - Write-Host " - $d" - } + if ($?) { + foreach ($d in $all) { + Write-Host " - $d" + } - Write-Host "Matching changes:" - $matching = @( - 'externals', - 'native', - 'scripts', - '.gitmodules' - ) - $requiresFull = (git diff-tree --no-commit-id --name-only -r HEAD~ HEAD @matching) - foreach ($d in $requiresFull) { - Write-Host " - $d" - } + Write-Host "Matching changes:" + $matching = @( + 'externals', + 'native', + 'scripts', + '.gitmodules' + ) + $requiresFull = (git diff-tree --no-commit-id --name-only -r HEAD~ HEAD @matching) + if ($?) { + foreach ($d in $requiresFull) { + Write-Host " - $d" + } - if (-not $requiresFull) { - Write-Host "Download-only build." - Write-Host "##vso[task.setvariable variable=DOWNLOAD_EXTERNALS]latest" - exit 0 + if (-not $requiresFull) { + Write-Host "Download-only build." + Write-Host "##vso[task.setvariable variable=DOWNLOAD_EXTERNALS]latest" + exit 0 + } + } } } diff --git a/scripts/vcvarsall.bat b/scripts/vcvarsall.bat new file mode 100644 index 0000000000..52a6e62855 --- /dev/null +++ b/scripts/vcvarsall.bat @@ -0,0 +1,33 @@ +@echo off + +REM Check if all three arguments are provided +if "%~2"=="" ( + echo Usage: %0 ^ ^ ^ + exit /b 1 +) + +set __VSCMD_ARG_NO_LOGO=1 +set VSCMD_START_DIR=%CD% + +REM Run vcvarsall.bat script +call "%~1\VC\Auxiliary\Build\vcvarsall.bat" %~2 +shift +shift + +REM drop the path to the VS install +set "args=" +:getRemainingArgs +if "%~1" neq "" ( + set ^"args=%args% %1" + shift /1 + goto :getRemainingArgs +) + +REM Check if vcvarsall.bat ran successfully +if %errorlevel% neq 0 ( + echo Error: Failed to run vcvarsall.bat + exit /b 1 +) + +REM Run the provided command +%args% diff --git a/source/SkiaSharp.Build.targets b/source/SkiaSharp.Build.targets index 94ccde57bc..b610868313 100644 --- a/source/SkiaSharp.Build.targets +++ b/source/SkiaSharp.Build.targets @@ -149,6 +149,9 @@ internal partial class VersionConstants { <_SignAssemblyAfterTargets> CoreCompile + <_SignAssemblyAfterTargets Condition="'$(CsWinRTIncludes)' != ''"> + CsWinRTReplaceForPatchedRuntime + + { + RenderFrame(); + tcs.SetResult(); + }); + tcs.Task.Wait(); } } } } } - -#endif diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/Egl.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/Egl.cs index ecd7d27168..957a824600 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/Egl.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/Egl.cs @@ -6,7 +6,7 @@ using EGLConfig = System.IntPtr; using EGLSurface = System.IntPtr; using EGLNativeDisplayType = System.IntPtr; -using EGLNativeWindowType = System.Object; +using EGLNativeWindowType = System.IntPtr; using glbool = System.Int32; namespace SkiaSharp.Views.GlesInterop @@ -94,7 +94,7 @@ internal static class Egl [DllImport(libEGL)] public static extern EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list); [DllImport(libEGL)] - public static extern EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, [MarshalAs(UnmanagedType.IInspectable)] EGLNativeWindowType win, int[] attrib_list); + public static extern EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, int[] attrib_list); [DllImport(libEGL)] public static extern glbool eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value); [DllImport(libEGL)] diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/GlesContext.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/GlesContext.cs index 8acfaa520e..6d39bfebc3 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/GlesContext.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/GlesContext.cs @@ -19,6 +19,8 @@ using EGLContext = System.IntPtr; using EGLConfig = System.IntPtr; using EGLSurface = System.IntPtr; +using SkiaSharp.Views.WinUI.Native; +using WinRT; namespace SkiaSharp.Views.GlesInterop { @@ -102,7 +104,7 @@ public void CreateSurface(SwapChainPanel panel, Size? renderSurfaceSize, float? PropertySetExtensions.AddSingle(surfaceCreationProperties, Egl.EGLRenderResolutionScaleProperty, resolutionScale.Value); } - surface = Egl.eglCreateWindowSurface(eglDisplay, eglConfig, surfaceCreationProperties, surfaceAttributes); + surface = Egl.eglCreateWindowSurface(eglDisplay, eglConfig, surfaceCreationProperties.As().ThisPtr, surfaceAttributes); if (surface == Egl.EGL_NO_SURFACE) { throw new Exception("Failed to create EGL surface"); diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/Interop/PropertySetExtensions.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/Interop/PropertySetExtensions.cs deleted file mode 100644 index 6b4ef50030..0000000000 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/Interop/PropertySetExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Runtime.InteropServices; -using Windows.Foundation; -using Windows.Foundation.Collections; - -#if WINDOWS -namespace SkiaSharp.Views.Windows -#else -namespace SkiaSharp.Views.UWP -#endif -{ - internal static class PropertySetExtensions - { - private const string libInterop = "SkiaSharp.Views.Interop.UWP.dll"; - - public static void AddSingle(this PropertySet properties, string key, float value) - { - PropertySet_AddSingle(properties, key, value); - } - - public static void AddSize(this PropertySet properties, string key, Size size) - { - PropertySet_AddSize(properties, key, (float)size.Width, (float)size.Height); - } - - public static void AddSize(this PropertySet properties, string key, float width, float height) - { - PropertySet_AddSize(properties, key, width, height); - } - - [DllImport(libInterop)] - private static extern void PropertySet_AddSingle( - [MarshalAs(UnmanagedType.IInspectable)] object properties, - [MarshalAs(UnmanagedType.HString)] string key, - float value); - - [DllImport(libInterop)] - private static extern void PropertySet_AddSize( - [MarshalAs(UnmanagedType.IInspectable)] object properties, - [MarshalAs(UnmanagedType.HString)] string key, - float width, float height); - } -} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SKSwapChainPanel.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SKSwapChainPanel.cs index d82f07fd3c..ce872b5db0 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SKSwapChainPanel.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SKSwapChainPanel.cs @@ -1,6 +1,4 @@ -#if !WINDOWS - -using System; +using System; using SkiaSharp.Views.GlesInterop; using Windows.Foundation; @@ -91,9 +89,7 @@ protected override void OnRenderFrame(Rect rect) using (new SKAutoCanvasRestore(canvas, true)) { // start drawing -#pragma warning disable CS0612 // Type or member is obsolete - OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo)); -#pragma warning restore CS0612 // Type or member is obsolete + OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType)); } // update the control @@ -127,5 +123,3 @@ protected override void OnDestroyingContext() } } } - -#endif diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SkiaSharp.Views.WinUI.csproj b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SkiaSharp.Views.WinUI.csproj index 76514d596b..61d49d9946 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SkiaSharp.Views.WinUI.csproj +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SkiaSharp.Views.WinUI.csproj @@ -20,6 +20,12 @@ + + + + + + diff --git a/source/SkiaSharpSource.Windows.slnf b/source/SkiaSharpSource.Windows.slnf index 3fc282a63b..b90c7f0fcf 100644 --- a/source/SkiaSharpSource.Windows.slnf +++ b/source/SkiaSharpSource.Windows.slnf @@ -20,6 +20,7 @@ "..\\binding\\SkiaSharp.NativeAssets.Tizen\\SkiaSharp.NativeAssets.Tizen.csproj", "..\\binding\\SkiaSharp.NativeAssets.WebAssembly\\SkiaSharp.NativeAssets.WebAssembly.csproj", "..\\binding\\SkiaSharp.NativeAssets.Win32\\SkiaSharp.NativeAssets.Win32.csproj", + "..\\binding\\SkiaSharp.NativeAssets.WinUI\\SkiaSharp.NativeAssets.WinUI.csproj", "..\\binding\\SkiaSharp.NativeAssets.iOS\\SkiaSharp.NativeAssets.iOS.csproj", "..\\binding\\SkiaSharp.NativeAssets.macOS\\SkiaSharp.NativeAssets.macOS.csproj", "..\\binding\\SkiaSharp.NativeAssets.tvOS\\SkiaSharp.NativeAssets.tvOS.csproj", diff --git a/source/SkiaSharpSource.sln b/source/SkiaSharpSource.sln index 0586d94f8f..20380709a4 100644 --- a/source/SkiaSharpSource.sln +++ b/source/SkiaSharpSource.sln @@ -85,6 +85,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.NativeAssets.WebA EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.NativeAssets.Win32", "..\binding\SkiaSharp.NativeAssets.Win32\SkiaSharp.NativeAssets.Win32.csproj", "{3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.NativeAssets.WinUI", "..\binding\SkiaSharp.NativeAssets.WinUI\SkiaSharp.NativeAssets.WinUI.csproj", "{3D2711DC-EAD2-4EE8-8A4D-83FB64897435}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp.NativeAssets.Android", "..\binding\HarfBuzzSharp.NativeAssets.Android\HarfBuzzSharp.NativeAssets.Android.csproj", "{BAF3A8BA-AC8A-4D28-811B-6A60F818E75B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp.NativeAssets.iOS", "..\binding\HarfBuzzSharp.NativeAssets.iOS\HarfBuzzSharp.NativeAssets.iOS.csproj", "{8C8F8386-9359-42F9-A5F5-83FB64897435}" @@ -233,6 +235,10 @@ Global {3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C}.Debug|Any CPU.Build.0 = Debug|Any CPU {3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C}.Release|Any CPU.ActiveCfg = Release|Any CPU {3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C}.Release|Any CPU.Build.0 = Release|Any CPU + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435}.Release|Any CPU.Build.0 = Release|Any CPU {BAF3A8BA-AC8A-4D28-811B-6A60F818E75B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BAF3A8BA-AC8A-4D28-811B-6A60F818E75B}.Debug|Any CPU.Build.0 = Debug|Any CPU {BAF3A8BA-AC8A-4D28-811B-6A60F818E75B}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -315,6 +321,7 @@ Global {4A0AF7AC-E18D-41A9-801D-F2BA659B20EB} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} {694D48BE-B381-45A3-BF94-4E3D439145D8} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} {3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} {BAF3A8BA-AC8A-4D28-811B-6A60F818E75B} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53} {8C8F8386-9359-42F9-A5F5-83FB64897435} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53} {59D12575-1395-4D08-BA5B-73A614F2AF6B} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53}