using System; using System.Buffers; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using Microsoft.CodeAnalysis; using SkiaSharp.Internals; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("SkiaSharp")] [assembly: AssemblyDescription("SkiaSharp is a cross-platform 2D graphics API for .NET platforms that can be used across mobile, server and desktop models to render images.")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyProduct("SkiaSharp")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyConfiguration("Release")] [assembly: InternalsVisibleTo("SkiaSharp.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")] [assembly: InternalsVisibleTo("SkiaSharp.Benchmarks, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")] [assembly: InternalsVisibleTo("SkiaSharp.HarfBuzz, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")] [assembly: InternalsVisibleTo("SkiaSharp.SceneGraph, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")] [assembly: InternalsVisibleTo("SkiaSharp.Skottie, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")] [assembly: AssemblyMetadata("IsTrimmable", "True")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyFileVersion("2.88.6.0")] [assembly: AssemblyInformationalVersion("2.88.6.0-e2c5c86249621857107c779af0f79b4d06613766")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.88.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Embedded] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } } internal class VersionConstants { public const string AssemblyVersion = "2.88.0.0"; public const string AssemblyFileVersion = "2.88.6.0"; public const string AssemblyInformationalVersion = "2.88.6.0-e2c5c86249621857107c779af0f79b4d06613766"; public const string GitSha = "-e2c5c86249621857107c779af0f79b4d06613766"; public const int Milestone = 88; public const int Increment = 1; } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Method, Inherited = false)] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } } namespace SkiaSharp { internal delegate Delegate GetMultiDelegateDelegate(Type index); internal delegate object UserDataDelegate(); internal static class DelegateProxies { public unsafe static readonly SKBitmapReleaseProxyDelegate SKBitmapReleaseDelegateProxy = SKBitmapReleaseDelegateProxyImplementation; public unsafe static readonly SKDataReleaseProxyDelegate SKDataReleaseDelegateProxy = SKDataReleaseDelegateProxyImplementation; public unsafe static readonly SKImageRasterReleaseProxyDelegate SKImageRasterReleaseDelegateProxy = SKImageRasterReleaseDelegateProxyImplementation; public unsafe static readonly SKImageRasterReleaseProxyDelegate SKImageRasterReleaseDelegateProxyForCoTaskMem = SKImageRasterReleaseDelegateProxyImplementationForCoTaskMem; public unsafe static readonly SKImageTextureReleaseProxyDelegate SKImageTextureReleaseDelegateProxy = SKImageTextureReleaseDelegateProxyImplementation; public unsafe static readonly SKSurfaceRasterReleaseProxyDelegate SKSurfaceReleaseDelegateProxy = SKSurfaceReleaseDelegateProxyImplementation; public unsafe static readonly GRGlGetProcProxyDelegate GRGlGetProcDelegateProxy = GRGlGetProcDelegateProxyImplementation; public unsafe static readonly GRVkGetProcProxyDelegate GRVkGetProcDelegateProxy = GRVkGetProcDelegateProxyImplementation; public unsafe static readonly SKGlyphPathProxyDelegate SKGlyphPathDelegateProxy = SKGlyphPathDelegateProxyImplementation; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T Create(object managedDel, T nativeDel, out GCHandle gch, out IntPtr contextPtr) { if (managedDel == null) { gch = default(GCHandle); contextPtr = IntPtr.Zero; return default(T); } gch = GCHandle.Alloc(managedDel); contextPtr = GCHandle.ToIntPtr(gch); return nativeDel; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Create(object managedDel, out GCHandle gch, out IntPtr contextPtr) { if (managedDel == null) { gch = default(GCHandle); contextPtr = IntPtr.Zero; } else { gch = GCHandle.Alloc(managedDel); contextPtr = GCHandle.ToIntPtr(gch); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T Get(IntPtr contextPtr, out GCHandle gch) { if (contextPtr == IntPtr.Zero) { gch = default(GCHandle); return default(T); } gch = GCHandle.FromIntPtr(contextPtr); return (T)gch.Target; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr CreateUserData(object userData, bool makeWeak = false) { userData = (makeWeak ? new WeakReference(userData) : userData); UserDataDelegate managedDel = () => userData; Create(managedDel, out var _, out var contextPtr); return contextPtr; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetUserData(IntPtr contextPtr, out GCHandle gch) { UserDataDelegate userDataDelegate = Get(contextPtr, out gch); object obj = userDataDelegate(); if (!(obj is WeakReference weakReference)) { return (T)obj; } return (T)weakReference.Target; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr CreateMulti(T1 wrappedDelegate1, T2 wrappedDelegate2) where T1 : Delegate where T2 : Delegate { GetMultiDelegateDelegate managedDel = delegate(Type type) { if (type == typeof(T1)) { return wrappedDelegate1; } if (type == typeof(T2)) { return wrappedDelegate2; } throw new ArgumentOutOfRangeException("type"); }; Create(managedDel, out var _, out var contextPtr); return contextPtr; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr CreateMulti(T1 wrappedDelegate1, T2 wrappedDelegate2, T3 wrappedDelegate3) where T1 : Delegate where T2 : Delegate where T3 : Delegate { GetMultiDelegateDelegate managedDel = delegate(Type type) { if (type == typeof(T1)) { return wrappedDelegate1; } if (type == typeof(T2)) { return wrappedDelegate2; } if (type == typeof(T3)) { return wrappedDelegate3; } throw new ArgumentOutOfRangeException("type"); }; Create(managedDel, out var _, out var contextPtr); return contextPtr; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetMulti(IntPtr contextPtr, out GCHandle gch) where T : Delegate { GetMultiDelegateDelegate getMultiDelegateDelegate = Get(contextPtr, out gch); return (T)getMultiDelegateDelegate(typeof(T)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void GetMulti(IntPtr contextPtr, out T1 wrappedDelegate1, out T2 wrappedDelegate2, out GCHandle gch) where T1 : Delegate where T2 : Delegate { GetMultiDelegateDelegate getMultiDelegateDelegate = Get(contextPtr, out gch); wrappedDelegate1 = (T1)getMultiDelegateDelegate(typeof(T1)); wrappedDelegate2 = (T2)getMultiDelegateDelegate(typeof(T2)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void GetMulti(IntPtr contextPtr, out T1 wrappedDelegate1, out T2 wrappedDelegate2, out T3 wrappedDelegate3, out GCHandle gch) where T1 : Delegate where T2 : Delegate where T3 : Delegate { GetMultiDelegateDelegate getMultiDelegateDelegate = Get(contextPtr, out gch); wrappedDelegate1 = (T1)getMultiDelegateDelegate(typeof(T1)); wrappedDelegate2 = (T2)getMultiDelegateDelegate(typeof(T2)); wrappedDelegate3 = (T3)getMultiDelegateDelegate(typeof(T3)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr CreateMultiUserData(T wrappedDelegate, object userData, bool makeWeak = false) where T : Delegate { userData = (makeWeak ? new WeakReference(userData) : userData); UserDataDelegate userDataDelegate = () => userData; GetMultiDelegateDelegate managedDel = delegate(Type type) { if (type == typeof(T)) { return wrappedDelegate; } if (type == typeof(UserDataDelegate)) { return userDataDelegate; } throw new ArgumentOutOfRangeException("type"); }; Create(managedDel, out var _, out var contextPtr); return contextPtr; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr CreateMultiUserData(T1 wrappedDelegate1, T2 wrappedDelegate2, object userData, bool makeWeak = false) where T1 : Delegate where T2 : Delegate { userData = (makeWeak ? new WeakReference(userData) : userData); UserDataDelegate userDataDelegate = () => userData; GetMultiDelegateDelegate managedDel = delegate(Type type) { if (type == typeof(T1)) { return wrappedDelegate1; } if (type == typeof(T2)) { return wrappedDelegate2; } if (type == typeof(UserDataDelegate)) { return userDataDelegate; } throw new ArgumentOutOfRangeException("type"); }; Create(managedDel, out var _, out var contextPtr); return contextPtr; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr CreateMultiUserData(T1 wrappedDelegate1, T2 wrappedDelegate2, T3 wrappedDelegate3, object userData, bool makeWeak = false) where T1 : Delegate where T2 : Delegate where T3 : Delegate { userData = (makeWeak ? new WeakReference(userData) : userData); UserDataDelegate userDataDelegate = () => userData; GetMultiDelegateDelegate managedDel = delegate(Type type) { if (type == typeof(T1)) { return wrappedDelegate1; } if (type == typeof(T2)) { return wrappedDelegate2; } if (type == typeof(T3)) { return wrappedDelegate3; } if (type == typeof(UserDataDelegate)) { return userDataDelegate; } throw new ArgumentOutOfRangeException("type"); }; Create(managedDel, out var _, out var contextPtr); return contextPtr; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TUserData GetMultiUserData(IntPtr contextPtr, out GCHandle gch) { GetMultiDelegateDelegate multi = Get(contextPtr, out gch); return GetUserData(multi); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void GetMultiUserData(IntPtr contextPtr, out T wrappedDelegate, out TUserData userData, out GCHandle gch) where T : Delegate { GetMultiDelegateDelegate getMultiDelegateDelegate = Get(contextPtr, out gch); wrappedDelegate = (T)getMultiDelegateDelegate(typeof(T)); userData = GetUserData(getMultiDelegateDelegate); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void GetMultiUserData(IntPtr contextPtr, out T1 wrappedDelegate1, out T2 wrappedDelegate2, out TUserData userData, out GCHandle gch) where T1 : Delegate where T2 : Delegate { GetMultiDelegateDelegate getMultiDelegateDelegate = Get(contextPtr, out gch); wrappedDelegate1 = (T1)getMultiDelegateDelegate(typeof(T1)); wrappedDelegate2 = (T2)getMultiDelegateDelegate(typeof(T2)); userData = GetUserData(getMultiDelegateDelegate); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void GetMultiUserData(IntPtr contextPtr, out T1 wrappedDelegate1, out T2 wrappedDelegate2, out T3 wrappedDelegate3, out TUserData userData, out GCHandle gch) where T1 : Delegate where T2 : Delegate where T3 : Delegate { GetMultiDelegateDelegate getMultiDelegateDelegate = Get(contextPtr, out gch); wrappedDelegate1 = (T1)getMultiDelegateDelegate(typeof(T1)); wrappedDelegate2 = (T2)getMultiDelegateDelegate(typeof(T2)); wrappedDelegate3 = (T3)getMultiDelegateDelegate(typeof(T3)); userData = GetUserData(getMultiDelegateDelegate); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static TUserData GetUserData(GetMultiDelegateDelegate multi) { UserDataDelegate userDataDelegate = (UserDataDelegate)multi(typeof(UserDataDelegate)); object obj = userDataDelegate(); if (!(obj is WeakReference weakReference)) { return (TUserData)obj; } return (TUserData)weakReference.Target; } [MonoPInvokeCallback(typeof(SKBitmapReleaseProxyDelegate))] private unsafe static void SKBitmapReleaseDelegateProxyImplementation(void* address, void* context) { GCHandle gch; SKBitmapReleaseDelegate sKBitmapReleaseDelegate = Get((IntPtr)context, out gch); try { sKBitmapReleaseDelegate((IntPtr)address, null); } finally { gch.Free(); } } [MonoPInvokeCallback(typeof(SKDataReleaseProxyDelegate))] private unsafe static void SKDataReleaseDelegateProxyImplementation(void* address, void* context) { GCHandle gch; SKDataReleaseDelegate sKDataReleaseDelegate = Get((IntPtr)context, out gch); try { sKDataReleaseDelegate((IntPtr)address, null); } finally { gch.Free(); } } [MonoPInvokeCallback(typeof(SKImageRasterReleaseProxyDelegate))] private unsafe static void SKImageRasterReleaseDelegateProxyImplementationForCoTaskMem(void* pixels, void* context) { Marshal.FreeCoTaskMem((IntPtr)pixels); } [MonoPInvokeCallback(typeof(SKImageRasterReleaseProxyDelegate))] private unsafe static void SKImageRasterReleaseDelegateProxyImplementation(void* pixels, void* context) { GCHandle gch; SKImageRasterReleaseDelegate sKImageRasterReleaseDelegate = Get((IntPtr)context, out gch); try { sKImageRasterReleaseDelegate((IntPtr)pixels, null); } finally { gch.Free(); } } [MonoPInvokeCallback(typeof(SKImageTextureReleaseProxyDelegate))] private unsafe static void SKImageTextureReleaseDelegateProxyImplementation(void* context) { GCHandle gch; SKImageTextureReleaseDelegate sKImageTextureReleaseDelegate = Get((IntPtr)context, out gch); try { sKImageTextureReleaseDelegate(null); } finally { gch.Free(); } } [MonoPInvokeCallback(typeof(SKSurfaceRasterReleaseProxyDelegate))] private unsafe static void SKSurfaceReleaseDelegateProxyImplementation(void* address, void* context) { GCHandle gch; SKSurfaceReleaseDelegate sKSurfaceReleaseDelegate = Get((IntPtr)context, out gch); try { sKSurfaceReleaseDelegate((IntPtr)address, null); } finally { gch.Free(); } } [MonoPInvokeCallback(typeof(GRGlGetProcProxyDelegate))] private unsafe static IntPtr GRGlGetProcDelegateProxyImplementation(void* context, void* name) { GCHandle gch; GRGlGetProcedureAddressDelegate gRGlGetProcedureAddressDelegate = Get((IntPtr)context, out gch); return gRGlGetProcedureAddressDelegate(Marshal.PtrToStringAnsi((IntPtr)name)); } [MonoPInvokeCallback(typeof(GRVkGetProcProxyDelegate))] private unsafe static IntPtr GRVkGetProcDelegateProxyImplementation(void* context, void* name, IntPtr instance, IntPtr device) { GCHandle gch; GRVkGetProcedureAddressDelegate gRVkGetProcedureAddressDelegate = Get((IntPtr)context, out gch); return gRVkGetProcedureAddressDelegate(Marshal.PtrToStringAnsi((IntPtr)name), instance, device); } [MonoPInvokeCallback(typeof(SKGlyphPathProxyDelegate))] private unsafe static void SKGlyphPathDelegateProxyImplementation(IntPtr pathOrNull, SKMatrix* matrix, void* context) { GCHandle gch; SKGlyphPathDelegate sKGlyphPathDelegate = Get((IntPtr)context, out gch); SKPath path = SKPath.GetObject(pathOrNull, owns: false); sKGlyphPathDelegate(path, *matrix); } } [AttributeUsage(AttributeTargets.Method)] internal sealed class MonoPInvokeCallbackAttribute : Attribute { public Type Type { get; private set; } public MonoPInvokeCallbackAttribute(Type type) { Type = type; } } internal struct HashCode { private static readonly uint s_seed = GenerateGlobalSeed(); private const uint Prime1 = 2654435761u; private const uint Prime2 = 2246822519u; private const uint Prime3 = 3266489917u; private const uint Prime4 = 668265263u; private const uint Prime5 = 374761393u; private uint _v1; private uint _v2; private uint _v3; private uint _v4; private uint _queue1; private uint _queue2; private uint _queue3; private uint _length; private static uint GenerateGlobalSeed() { Random random = new Random(); return (uint)random.Next(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Initialize(out uint v1, out uint v2, out uint v3, out uint v4) { v1 = (uint)((int)s_seed + -1640531535 + -2048144777); v2 = s_seed + 2246822519u; v3 = s_seed; v4 = s_seed - 2654435761u; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint Round(uint hash, uint input) { return RotateLeft(hash + (uint)((int)input * -2048144777), 13) * 2654435761u; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint QueueRound(uint hash, uint queuedValue) { return RotateLeft(hash + (uint)((int)queuedValue * -1028477379), 17) * 668265263; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint MixState(uint v1, uint v2, uint v3, uint v4) { return RotateLeft(v1, 1) + RotateLeft(v2, 7) + RotateLeft(v3, 12) + RotateLeft(v4, 18); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint RotateLeft(uint value, int offset) { return (value << offset) | (value >> 32 - offset); } private static uint MixEmptyState() { return s_seed + 374761393; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint MixFinal(uint hash) { hash ^= hash >> 15; hash *= 2246822519u; hash ^= hash >> 13; hash *= 3266489917u; hash ^= hash >> 16; return hash; } public unsafe void Add(void* value) { Add((value != null) ? ((IntPtr)value).GetHashCode() : 0); } public void Add(T value) { Add(value?.GetHashCode() ?? 0); } private void Add(int value) { uint num = _length++; switch (num % 4) { case 0u: _queue1 = (uint)value; return; case 1u: _queue2 = (uint)value; return; case 2u: _queue3 = (uint)value; return; } if (num == 3) { Initialize(out _v1, out _v2, out _v3, out _v4); } _v1 = Round(_v1, _queue1); _v2 = Round(_v2, _queue2); _v3 = Round(_v3, _queue3); _v4 = Round(_v4, (uint)value); } public int ToHashCode() { uint length = _length; uint num = length % 4; uint num2 = ((length < 4) ? MixEmptyState() : MixState(_v1, _v2, _v3, _v4)); num2 += length * 4; if (num != 0) { num2 = QueueRound(num2, _queue1); if (num > 1) { num2 = QueueRound(num2, _queue2); if (num > 2) { num2 = QueueRound(num2, _queue3); } } } return (int)MixFinal(num2); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKEncodedOrigin instead.")] public enum SKCodecOrigin { TopLeft = 1, TopRight, BottomRight, BottomLeft, LeftTop, RightTop, RightBottom, LeftBottom } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKTextEncoding instead.")] public enum SKEncoding { Utf8, Utf16, Utf32 } public enum SKFontStyleWeight { Invisible = 0, Thin = 100, ExtraLight = 200, Light = 300, Normal = 400, Medium = 500, SemiBold = 600, Bold = 700, ExtraBold = 800, Black = 900, ExtraBlack = 1000 } public enum SKFontStyleWidth { UltraCondensed = 1, ExtraCondensed, Condensed, SemiCondensed, Normal, SemiExpanded, Expanded, ExtraExpanded, UltraExpanded } public enum SKColorType { Unknown, Alpha8, Rgb565, Argb4444, Rgba8888, Rgb888x, Bgra8888, Rgba1010102, Rgb101010x, Gray8, RgbaF16, RgbaF16Clamped, RgbaF32, Rg88, AlphaF16, RgF16, Alpha16, Rg1616, Rgba16161616, Bgra1010102, Bgr101010x } public static class SkiaExtensions { public static bool IsBgr(this SKPixelGeometry pg) { if (pg != SKPixelGeometry.BgrHorizontal) { return pg == SKPixelGeometry.BgrVertical; } return true; } public static bool IsRgb(this SKPixelGeometry pg) { if (pg != SKPixelGeometry.RgbHorizontal) { return pg == SKPixelGeometry.RgbVertical; } return true; } public static bool IsVertical(this SKPixelGeometry pg) { if (pg != SKPixelGeometry.BgrVertical) { return pg == SKPixelGeometry.RgbVertical; } return true; } public static bool IsHorizontal(this SKPixelGeometry pg) { if (pg != SKPixelGeometry.BgrHorizontal) { return pg == SKPixelGeometry.RgbHorizontal; } return true; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public static SKTextEncoding ToTextEncoding(this SKEncoding encoding) { return encoding switch { SKEncoding.Utf8 => SKTextEncoding.Utf8, SKEncoding.Utf16 => SKTextEncoding.Utf16, SKEncoding.Utf32 => SKTextEncoding.Utf32, _ => throw new ArgumentOutOfRangeException("encoding"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] internal static SKEncoding ToEncoding(this SKTextEncoding encoding) { return encoding switch { SKTextEncoding.Utf8 => SKEncoding.Utf8, SKTextEncoding.Utf16 => SKEncoding.Utf16, SKTextEncoding.Utf32 => SKEncoding.Utf32, _ => throw new ArgumentOutOfRangeException("encoding"), }; } public static int GetBytesPerPixel(this SKColorType colorType) { return colorType switch { SKColorType.Unknown => 0, SKColorType.Alpha8 => 1, SKColorType.Gray8 => 1, SKColorType.Rgb565 => 2, SKColorType.Argb4444 => 2, SKColorType.Rg88 => 2, SKColorType.Alpha16 => 2, SKColorType.AlphaF16 => 2, SKColorType.Bgra8888 => 4, SKColorType.Bgra1010102 => 4, SKColorType.Bgr101010x => 4, SKColorType.Rgba8888 => 4, SKColorType.Rgb888x => 4, SKColorType.Rgba1010102 => 4, SKColorType.Rgb101010x => 4, SKColorType.Rg1616 => 4, SKColorType.RgF16 => 4, SKColorType.RgbaF16Clamped => 8, SKColorType.RgbaF16 => 8, SKColorType.Rgba16161616 => 8, SKColorType.RgbaF32 => 16, _ => throw new ArgumentOutOfRangeException("colorType"), }; } public static SKAlphaType GetAlphaType(this SKColorType colorType, SKAlphaType alphaType = SKAlphaType.Premul) { switch (colorType) { case SKColorType.Unknown: alphaType = SKAlphaType.Unknown; break; case SKColorType.Alpha8: case SKColorType.AlphaF16: case SKColorType.Alpha16: if (SKAlphaType.Unpremul == alphaType) { alphaType = SKAlphaType.Premul; } break; case SKColorType.Rgb565: case SKColorType.Rgb888x: case SKColorType.Rgb101010x: case SKColorType.Gray8: case SKColorType.Rg88: case SKColorType.RgF16: case SKColorType.Rg1616: case SKColorType.Bgr101010x: alphaType = SKAlphaType.Opaque; break; default: throw new ArgumentOutOfRangeException("colorType"); case SKColorType.Argb4444: case SKColorType.Rgba8888: case SKColorType.Bgra8888: case SKColorType.Rgba1010102: case SKColorType.RgbaF16: case SKColorType.RgbaF16Clamped: case SKColorType.RgbaF32: case SKColorType.Rgba16161616: case SKColorType.Bgra1010102: break; } return alphaType; } internal static GRBackendNative ToNative(this GRBackend backend) { return backend switch { GRBackend.Metal => GRBackendNative.Metal, GRBackend.OpenGL => GRBackendNative.OpenGL, GRBackend.Vulkan => GRBackendNative.Vulkan, GRBackend.Dawn => GRBackendNative.Dawn, GRBackend.Direct3D => GRBackendNative.Direct3D, _ => throw new ArgumentOutOfRangeException("backend"), }; } internal static GRBackend FromNative(this GRBackendNative backend) { return backend switch { GRBackendNative.Metal => GRBackend.Metal, GRBackendNative.OpenGL => GRBackend.OpenGL, GRBackendNative.Vulkan => GRBackend.Vulkan, GRBackendNative.Dawn => GRBackend.Dawn, GRBackendNative.Direct3D => GRBackend.Direct3D, _ => throw new ArgumentOutOfRangeException("backend"), }; } internal static SKColorTypeNative ToNative(this SKColorType colorType) { return colorType switch { SKColorType.Unknown => SKColorTypeNative.Unknown, SKColorType.Alpha8 => SKColorTypeNative.Alpha8, SKColorType.Rgb565 => SKColorTypeNative.Rgb565, SKColorType.Argb4444 => SKColorTypeNative.Argb4444, SKColorType.Rgba8888 => SKColorTypeNative.Rgba8888, SKColorType.Rgb888x => SKColorTypeNative.Rgb888x, SKColorType.Bgra8888 => SKColorTypeNative.Bgra8888, SKColorType.Rgba1010102 => SKColorTypeNative.Rgba1010102, SKColorType.Rgb101010x => SKColorTypeNative.Rgb101010x, SKColorType.Gray8 => SKColorTypeNative.Gray8, SKColorType.RgbaF16Clamped => SKColorTypeNative.RgbaF16Norm, SKColorType.RgbaF16 => SKColorTypeNative.RgbaF16, SKColorType.RgbaF32 => SKColorTypeNative.RgbaF32, SKColorType.Rg88 => SKColorTypeNative.R8g8Unorm, SKColorType.AlphaF16 => SKColorTypeNative.A16Float, SKColorType.RgF16 => SKColorTypeNative.R16g16Float, SKColorType.Alpha16 => SKColorTypeNative.A16Unorm, SKColorType.Rg1616 => SKColorTypeNative.R16g16Unorm, SKColorType.Rgba16161616 => SKColorTypeNative.R16g16b16a16Unorm, SKColorType.Bgra1010102 => SKColorTypeNative.Bgra1010102, SKColorType.Bgr101010x => SKColorTypeNative.Bgr101010x, _ => throw new ArgumentOutOfRangeException("colorType"), }; } internal static SKColorType FromNative(this SKColorTypeNative colorType) { return colorType switch { SKColorTypeNative.Unknown => SKColorType.Unknown, SKColorTypeNative.Alpha8 => SKColorType.Alpha8, SKColorTypeNative.Rgb565 => SKColorType.Rgb565, SKColorTypeNative.Argb4444 => SKColorType.Argb4444, SKColorTypeNative.Rgba8888 => SKColorType.Rgba8888, SKColorTypeNative.Rgb888x => SKColorType.Rgb888x, SKColorTypeNative.Bgra8888 => SKColorType.Bgra8888, SKColorTypeNative.Rgba1010102 => SKColorType.Rgba1010102, SKColorTypeNative.Rgb101010x => SKColorType.Rgb101010x, SKColorTypeNative.Gray8 => SKColorType.Gray8, SKColorTypeNative.RgbaF16Norm => SKColorType.RgbaF16Clamped, SKColorTypeNative.RgbaF16 => SKColorType.RgbaF16, SKColorTypeNative.RgbaF32 => SKColorType.RgbaF32, SKColorTypeNative.R8g8Unorm => SKColorType.Rg88, SKColorTypeNative.A16Float => SKColorType.AlphaF16, SKColorTypeNative.R16g16Float => SKColorType.RgF16, SKColorTypeNative.A16Unorm => SKColorType.Alpha16, SKColorTypeNative.R16g16Unorm => SKColorType.Rg1616, SKColorTypeNative.R16g16b16a16Unorm => SKColorType.Rgba16161616, SKColorTypeNative.Bgra1010102 => SKColorType.Bgra1010102, SKColorTypeNative.Bgr101010x => SKColorType.Bgr101010x, _ => throw new ArgumentOutOfRangeException("colorType"), }; } public static uint ToGlSizedFormat(this SKColorType colorType) { return colorType switch { SKColorType.Unknown => 0u, SKColorType.Alpha8 => 32828u, SKColorType.Gray8 => 32832u, SKColorType.Rgb565 => 36194u, SKColorType.Argb4444 => 32854u, SKColorType.Rgba8888 => 32856u, SKColorType.Rgb888x => 32849u, SKColorType.Bgra8888 => 37793u, SKColorType.Rgba1010102 => 32857u, SKColorType.AlphaF16 => 33325u, SKColorType.RgbaF16 => 34842u, SKColorType.RgbaF16Clamped => 34842u, SKColorType.Alpha16 => 33322u, SKColorType.Rg1616 => 33324u, SKColorType.Rgba16161616 => 32859u, SKColorType.RgF16 => 33327u, SKColorType.Rg88 => 33323u, SKColorType.Rgb101010x => 0u, SKColorType.RgbaF32 => 0u, _ => throw new ArgumentOutOfRangeException("colorType"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKColorType instead.")] public static uint ToGlSizedFormat(this GRPixelConfig config) { return config switch { GRPixelConfig.Unknown => 0u, GRPixelConfig.Alpha8 => 32828u, GRPixelConfig.Alpha8AsAlpha => 32828u, GRPixelConfig.Alpha8AsRed => 32828u, GRPixelConfig.Gray8 => 32832u, GRPixelConfig.Gray8AsLum => 32832u, GRPixelConfig.Gray8AsRed => 32832u, GRPixelConfig.Rgb565 => 36194u, GRPixelConfig.Rgba4444 => 32854u, GRPixelConfig.Rgba8888 => 32856u, GRPixelConfig.Rgb888 => 32849u, GRPixelConfig.Rgb888x => 32856u, GRPixelConfig.Rg88 => 33323u, GRPixelConfig.Bgra8888 => 37793u, GRPixelConfig.Srgba8888 => 35907u, GRPixelConfig.Rgba1010102 => 32857u, GRPixelConfig.AlphaHalf => 33325u, GRPixelConfig.AlphaHalfAsLum => 34846u, GRPixelConfig.AlphaHalfAsRed => 33325u, GRPixelConfig.RgbaHalf => 34842u, GRPixelConfig.RgbaHalfClamped => 34842u, GRPixelConfig.RgbEtc1 => 36196u, GRPixelConfig.Alpha16 => 33322u, GRPixelConfig.Rg1616 => 33324u, GRPixelConfig.Rgba16161616 => 32859u, GRPixelConfig.RgHalf => 33327u, _ => throw new ArgumentOutOfRangeException("config"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKColorType instead.")] public static GRPixelConfig ToPixelConfig(this SKColorType colorType) { return colorType switch { SKColorType.Unknown => GRPixelConfig.Unknown, SKColorType.Alpha8 => GRPixelConfig.Alpha8, SKColorType.Gray8 => GRPixelConfig.Gray8, SKColorType.Rgb565 => GRPixelConfig.Rgb565, SKColorType.Argb4444 => GRPixelConfig.Rgba4444, SKColorType.Rgba8888 => GRPixelConfig.Rgba8888, SKColorType.Rgb888x => GRPixelConfig.Rgb888, SKColorType.Bgra8888 => GRPixelConfig.Bgra8888, SKColorType.Rgba1010102 => GRPixelConfig.Rgba1010102, SKColorType.Bgra1010102 => GRPixelConfig.Unknown, SKColorType.AlphaF16 => GRPixelConfig.AlphaHalf, SKColorType.RgbaF16 => GRPixelConfig.RgbaHalf, SKColorType.RgbaF16Clamped => GRPixelConfig.RgbaHalfClamped, SKColorType.Alpha16 => GRPixelConfig.Alpha16, SKColorType.Rg1616 => GRPixelConfig.Rg1616, SKColorType.Rgba16161616 => GRPixelConfig.Rgba16161616, SKColorType.RgF16 => GRPixelConfig.RgHalf, SKColorType.Rg88 => GRPixelConfig.Rg88, SKColorType.Rgb101010x => GRPixelConfig.Unknown, SKColorType.Bgr101010x => GRPixelConfig.Unknown, SKColorType.RgbaF32 => GRPixelConfig.Unknown, _ => throw new ArgumentOutOfRangeException("colorType"), }; } [Obsolete("Use SKColorType instead.")] public static SKColorType ToColorType(this GRPixelConfig config) { return config switch { GRPixelConfig.Unknown => SKColorType.Unknown, GRPixelConfig.Alpha8 => SKColorType.Alpha8, GRPixelConfig.Gray8 => SKColorType.Gray8, GRPixelConfig.Rgb565 => SKColorType.Rgb565, GRPixelConfig.Rgba4444 => SKColorType.Argb4444, GRPixelConfig.Rgba8888 => SKColorType.Rgba8888, GRPixelConfig.Rgb888 => SKColorType.Rgb888x, GRPixelConfig.Bgra8888 => SKColorType.Bgra8888, GRPixelConfig.Srgba8888 => SKColorType.Rgba8888, GRPixelConfig.Rgba1010102 => SKColorType.Rgba1010102, GRPixelConfig.AlphaHalf => SKColorType.AlphaF16, GRPixelConfig.RgbaHalf => SKColorType.RgbaF16, GRPixelConfig.Alpha8AsAlpha => SKColorType.Alpha8, GRPixelConfig.Alpha8AsRed => SKColorType.Alpha8, GRPixelConfig.AlphaHalfAsLum => SKColorType.AlphaF16, GRPixelConfig.AlphaHalfAsRed => SKColorType.AlphaF16, GRPixelConfig.Gray8AsLum => SKColorType.Gray8, GRPixelConfig.Gray8AsRed => SKColorType.Gray8, GRPixelConfig.RgbaHalfClamped => SKColorType.RgbaF16Clamped, GRPixelConfig.Alpha16 => SKColorType.Alpha16, GRPixelConfig.Rg1616 => SKColorType.Rg1616, GRPixelConfig.Rgba16161616 => SKColorType.Rgba16161616, GRPixelConfig.RgHalf => SKColorType.RgF16, GRPixelConfig.Rg88 => SKColorType.Rg88, GRPixelConfig.Rgb888x => SKColorType.Rgb888x, GRPixelConfig.RgbEtc1 => SKColorType.Rgb888x, _ => throw new ArgumentOutOfRangeException("config"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public static SKFilterQuality ToFilterQuality(this SKBitmapResizeMethod method) { switch (method) { case SKBitmapResizeMethod.Box: case SKBitmapResizeMethod.Triangle: return SKFilterQuality.Low; case SKBitmapResizeMethod.Lanczos3: return SKFilterQuality.Medium; case SKBitmapResizeMethod.Hamming: case SKBitmapResizeMethod.Mitchell: return SKFilterQuality.High; default: return SKFilterQuality.Medium; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public static SKColorSpaceTransferFn ToColorSpaceTransferFn(this SKColorSpaceRenderTargetGamma gamma) { return gamma switch { SKColorSpaceRenderTargetGamma.Linear => SKColorSpaceTransferFn.Linear, SKColorSpaceRenderTargetGamma.Srgb => SKColorSpaceTransferFn.Srgb, _ => throw new ArgumentOutOfRangeException("gamma"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public static SKColorSpaceTransferFn ToColorSpaceTransferFn(this SKNamedGamma gamma) { return gamma switch { SKNamedGamma.Linear => SKColorSpaceTransferFn.Linear, SKNamedGamma.Srgb => SKColorSpaceTransferFn.Srgb, SKNamedGamma.TwoDotTwoCurve => SKColorSpaceTransferFn.TwoDotTwo, SKNamedGamma.NonStandard => SKColorSpaceTransferFn.Empty, _ => throw new ArgumentOutOfRangeException("gamma"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public static SKColorSpaceXyz ToColorSpaceXyz(this SKColorSpaceGamut gamut) { return gamut switch { SKColorSpaceGamut.AdobeRgb => SKColorSpaceXyz.AdobeRgb, SKColorSpaceGamut.Dcip3D65 => SKColorSpaceXyz.Dcip3, SKColorSpaceGamut.Rec2020 => SKColorSpaceXyz.Rec2020, SKColorSpaceGamut.Srgb => SKColorSpaceXyz.Srgb, _ => throw new ArgumentOutOfRangeException("gamut"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public static SKColorSpaceXyz ToColorSpaceXyz(this SKMatrix44 matrix) { if (matrix == null) { throw new ArgumentNullException("matrix"); } float[] array = matrix.ToRowMajor(); return new SKColorSpaceXyz(array[0], array[1], array[2], array[4], array[5], array[6], array[8], array[9], array[10]); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKColorChannel instead.")] public static SKColorChannel ToColorChannel(this SKDisplacementMapEffectChannelSelectorType channelSelectorType) { return channelSelectorType switch { SKDisplacementMapEffectChannelSelectorType.R => SKColorChannel.R, SKDisplacementMapEffectChannelSelectorType.G => SKColorChannel.G, SKDisplacementMapEffectChannelSelectorType.B => SKColorChannel.B, SKDisplacementMapEffectChannelSelectorType.A => SKColorChannel.A, _ => SKColorChannel.B, }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKShaderTileMode instead.")] public static SKShaderTileMode ToShaderTileMode(this SKMatrixConvolutionTileMode tileMode) { return tileMode switch { SKMatrixConvolutionTileMode.Clamp => SKShaderTileMode.Clamp, SKMatrixConvolutionTileMode.Repeat => SKShaderTileMode.Repeat, _ => SKShaderTileMode.Decal, }; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKSurfaceProperties instead.")] public struct SKSurfaceProps : IEquatable { public SKPixelGeometry PixelGeometry { get; set; } public SKSurfacePropsFlags Flags { get; set; } public readonly bool Equals(SKSurfaceProps obj) { if (PixelGeometry == obj.PixelGeometry) { return Flags == obj.Flags; } return false; } public override readonly bool Equals(object obj) { if (obj is SKSurfaceProps obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKSurfaceProps left, SKSurfaceProps right) { return left.Equals(right); } public static bool operator !=(SKSurfaceProps left, SKSurfaceProps right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(PixelGeometry); hashCode.Add(Flags); return hashCode.ToHashCode(); } } public struct SKCodecOptions : IEquatable { public static readonly SKCodecOptions Default; public SKZeroInitialized ZeroInitialized { get; set; } public SKRectI? Subset { get; set; } public readonly bool HasSubset => Subset.HasValue; public int FrameIndex { get; set; } public int PriorFrame { get; set; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public SKTransferFunctionBehavior PremulBehavior { readonly get { return SKTransferFunctionBehavior.Respect; } set { } } static SKCodecOptions() { Default = new SKCodecOptions(SKZeroInitialized.No); } public SKCodecOptions(SKZeroInitialized zeroInitialized) { ZeroInitialized = zeroInitialized; Subset = null; FrameIndex = 0; PriorFrame = -1; } public SKCodecOptions(SKZeroInitialized zeroInitialized, SKRectI subset) { ZeroInitialized = zeroInitialized; Subset = subset; FrameIndex = 0; PriorFrame = -1; } public SKCodecOptions(SKRectI subset) { ZeroInitialized = SKZeroInitialized.No; Subset = subset; FrameIndex = 0; PriorFrame = -1; } public SKCodecOptions(int frameIndex) { ZeroInitialized = SKZeroInitialized.No; Subset = null; FrameIndex = frameIndex; PriorFrame = -1; } public SKCodecOptions(int frameIndex, int priorFrame) { ZeroInitialized = SKZeroInitialized.No; Subset = null; FrameIndex = frameIndex; PriorFrame = priorFrame; } public readonly bool Equals(SKCodecOptions obj) { if (ZeroInitialized == obj.ZeroInitialized) { SKRectI? subset = Subset; SKRectI? subset2 = obj.Subset; if (subset.HasValue == subset2.HasValue && (!subset.HasValue || subset.GetValueOrDefault() == subset2.GetValueOrDefault()) && FrameIndex == obj.FrameIndex) { return PriorFrame == obj.PriorFrame; } } return false; } public override readonly bool Equals(object obj) { if (obj is SKCodecOptions obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKCodecOptions left, SKCodecOptions right) { return left.Equals(right); } public static bool operator !=(SKCodecOptions left, SKCodecOptions right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(ZeroInitialized); hashCode.Add(Subset); hashCode.Add(FrameIndex); hashCode.Add(PriorFrame); return hashCode.ToHashCode(); } } public struct SKFontMetrics : IEquatable { private const uint flagsUnderlineThicknessIsValid = 1u; private const uint flagsUnderlinePositionIsValid = 2u; private const uint flagsStrikeoutThicknessIsValid = 4u; private const uint flagsStrikeoutPositionIsValid = 8u; private uint fFlags; private float fTop; private float fAscent; private float fDescent; private float fBottom; private float fLeading; private float fAvgCharWidth; private float fMaxCharWidth; private float fXMin; private float fXMax; private float fXHeight; private float fCapHeight; private float fUnderlineThickness; private float fUnderlinePosition; private float fStrikeoutThickness; private float fStrikeoutPosition; public readonly float Top => fTop; public readonly float Ascent => fAscent; public readonly float Descent => fDescent; public readonly float Bottom => fBottom; public readonly float Leading => fLeading; public readonly float AverageCharacterWidth => fAvgCharWidth; public readonly float MaxCharacterWidth => fMaxCharWidth; public readonly float XMin => fXMin; public readonly float XMax => fXMax; public readonly float XHeight => fXHeight; public readonly float CapHeight => fCapHeight; public readonly float? UnderlineThickness => GetIfValid(fUnderlineThickness, 1u); public readonly float? UnderlinePosition => GetIfValid(fUnderlinePosition, 2u); public readonly float? StrikeoutThickness => GetIfValid(fStrikeoutThickness, 4u); public readonly float? StrikeoutPosition => GetIfValid(fStrikeoutPosition, 8u); private readonly float? GetIfValid(float value, uint flag) { if ((fFlags & flag) != flag) { return null; } return value; } public readonly bool Equals(SKFontMetrics obj) { if (fFlags == obj.fFlags && fTop == obj.fTop && fAscent == obj.fAscent && fDescent == obj.fDescent && fBottom == obj.fBottom && fLeading == obj.fLeading && fAvgCharWidth == obj.fAvgCharWidth && fMaxCharWidth == obj.fMaxCharWidth && fXMin == obj.fXMin && fXMax == obj.fXMax && fXHeight == obj.fXHeight && fCapHeight == obj.fCapHeight && fUnderlineThickness == obj.fUnderlineThickness && fUnderlinePosition == obj.fUnderlinePosition && fStrikeoutThickness == obj.fStrikeoutThickness) { return fStrikeoutPosition == obj.fStrikeoutPosition; } return false; } public override readonly bool Equals(object obj) { if (obj is SKFontMetrics obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKFontMetrics left, SKFontMetrics right) { return left.Equals(right); } public static bool operator !=(SKFontMetrics left, SKFontMetrics right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fFlags); hashCode.Add(fTop); hashCode.Add(fAscent); hashCode.Add(fDescent); hashCode.Add(fBottom); hashCode.Add(fLeading); hashCode.Add(fAvgCharWidth); hashCode.Add(fMaxCharWidth); hashCode.Add(fXMin); hashCode.Add(fXMax); hashCode.Add(fXHeight); hashCode.Add(fCapHeight); hashCode.Add(fUnderlineThickness); hashCode.Add(fUnderlinePosition); hashCode.Add(fStrikeoutThickness); hashCode.Add(fStrikeoutPosition); return hashCode.ToHashCode(); } } public struct SKLattice : IEquatable { public int[] XDivs { get; set; } public int[] YDivs { get; set; } public SKLatticeRectType[] RectTypes { get; set; } public SKRectI? Bounds { get; set; } public SKColor[] Colors { get; set; } public readonly bool Equals(SKLattice obj) { if (XDivs == obj.XDivs && YDivs == obj.YDivs && RectTypes == obj.RectTypes && Bounds == obj.Bounds) { return Colors == obj.Colors; } return false; } public override readonly bool Equals(object obj) { if (obj is SKLattice obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKLattice left, SKLattice right) { return left.Equals(right); } public static bool operator !=(SKLattice left, SKLattice right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(XDivs); hashCode.Add(YDivs); hashCode.Add(RectTypes); hashCode.Add(Bounds); hashCode.Add(Colors); return hashCode.ToHashCode(); } } internal struct SKTimeDateTimeInternal : IEquatable { public short fTimeZoneMinutes; public ushort fYear; public byte fMonth; public byte fDayOfWeek; public byte fDay; public byte fHour; public byte fMinute; public byte fSecond; public static SKTimeDateTimeInternal Create(DateTime datetime) { int num = datetime.Hour - datetime.ToUniversalTime().Hour; return new SKTimeDateTimeInternal { fTimeZoneMinutes = (short)(num * 60), fYear = (ushort)datetime.Year, fMonth = (byte)datetime.Month, fDayOfWeek = (byte)datetime.DayOfWeek, fDay = (byte)datetime.Day, fHour = (byte)datetime.Hour, fMinute = (byte)datetime.Minute, fSecond = (byte)datetime.Second }; } public readonly bool Equals(SKTimeDateTimeInternal obj) { if (fTimeZoneMinutes == obj.fTimeZoneMinutes && fYear == obj.fYear && fMonth == obj.fMonth && fDayOfWeek == obj.fDayOfWeek && fDay == obj.fDay && fHour == obj.fHour && fMinute == obj.fMinute) { return fSecond == obj.fSecond; } return false; } public override readonly bool Equals(object obj) { if (obj is SKTimeDateTimeInternal obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKTimeDateTimeInternal left, SKTimeDateTimeInternal right) { return left.Equals(right); } public static bool operator !=(SKTimeDateTimeInternal left, SKTimeDateTimeInternal right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fTimeZoneMinutes); hashCode.Add(fYear); hashCode.Add(fMonth); hashCode.Add(fDayOfWeek); hashCode.Add(fDay); hashCode.Add(fHour); hashCode.Add(fMinute); hashCode.Add(fSecond); return hashCode.ToHashCode(); } } public struct SKDocumentPdfMetadata : IEquatable { public const float DefaultRasterDpi = 72f; public const int DefaultEncodingQuality = 101; public static readonly SKDocumentPdfMetadata Default; public string Title { get; set; } public string Author { get; set; } public string Subject { get; set; } public string Keywords { get; set; } public string Creator { get; set; } public string Producer { get; set; } public DateTime? Creation { get; set; } public DateTime? Modified { get; set; } public float RasterDpi { get; set; } public bool PdfA { get; set; } public int EncodingQuality { get; set; } static SKDocumentPdfMetadata() { Default = new SKDocumentPdfMetadata { RasterDpi = 72f, PdfA = false, EncodingQuality = 101 }; } public SKDocumentPdfMetadata(float rasterDpi) { Title = null; Author = null; Subject = null; Keywords = null; Creator = null; Producer = null; Creation = null; Modified = null; RasterDpi = rasterDpi; PdfA = false; EncodingQuality = 101; } public SKDocumentPdfMetadata(int encodingQuality) { Title = null; Author = null; Subject = null; Keywords = null; Creator = null; Producer = null; Creation = null; Modified = null; RasterDpi = 72f; PdfA = false; EncodingQuality = encodingQuality; } public SKDocumentPdfMetadata(float rasterDpi, int encodingQuality) { Title = null; Author = null; Subject = null; Keywords = null; Creator = null; Producer = null; Creation = null; Modified = null; RasterDpi = rasterDpi; PdfA = false; EncodingQuality = encodingQuality; } public readonly bool Equals(SKDocumentPdfMetadata obj) { if (Title == obj.Title && Author == obj.Author && Subject == obj.Subject && Keywords == obj.Keywords && Creator == obj.Creator && Producer == obj.Producer && Creation == obj.Creation) { DateTime? modified = Modified; DateTime? modified2 = obj.Modified; if (modified.HasValue == modified2.HasValue && (!modified.HasValue || modified.GetValueOrDefault() == modified2.GetValueOrDefault()) && RasterDpi == obj.RasterDpi && PdfA == obj.PdfA) { return EncodingQuality == obj.EncodingQuality; } } return false; } public override readonly bool Equals(object obj) { if (obj is SKDocumentPdfMetadata obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKDocumentPdfMetadata left, SKDocumentPdfMetadata right) { return left.Equals(right); } public static bool operator !=(SKDocumentPdfMetadata left, SKDocumentPdfMetadata right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(Title); hashCode.Add(Author); hashCode.Add(Subject); hashCode.Add(Keywords); hashCode.Add(Creator); hashCode.Add(Producer); hashCode.Add(Creation); hashCode.Add(Modified); hashCode.Add(RasterDpi); hashCode.Add(PdfA); hashCode.Add(EncodingQuality); return hashCode.ToHashCode(); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] [Flags] public enum SKColorSpaceFlags { None = 0, NonLinearBlending = 1 } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public enum SKTransferFunctionBehavior { Ignore = 1, Respect = 0 } public struct SKHighContrastConfig : IEquatable { public static readonly SKHighContrastConfig Default; private byte fGrayscale; private SKHighContrastConfigInvertStyle fInvertStyle; private float fContrast; public readonly bool IsValid { get { if (fInvertStyle >= SKHighContrastConfigInvertStyle.NoInvert && fInvertStyle <= SKHighContrastConfigInvertStyle.InvertLightness && (double)fContrast >= -1.0) { return (double)fContrast <= 1.0; } return false; } } public bool Grayscale { readonly get { return fGrayscale > 0; } set { fGrayscale = (value ? ((byte)1) : ((byte)0)); } } public SKHighContrastConfigInvertStyle InvertStyle { readonly get { return fInvertStyle; } set { fInvertStyle = value; } } public float Contrast { readonly get { return fContrast; } set { fContrast = value; } } static SKHighContrastConfig() { Default = new SKHighContrastConfig(grayscale: false, SKHighContrastConfigInvertStyle.NoInvert, 0f); } public SKHighContrastConfig(bool grayscale, SKHighContrastConfigInvertStyle invertStyle, float contrast) { fGrayscale = (grayscale ? ((byte)1) : ((byte)0)); fInvertStyle = invertStyle; fContrast = contrast; } public readonly bool Equals(SKHighContrastConfig obj) { if (fGrayscale == obj.fGrayscale && fInvertStyle == obj.fInvertStyle) { return fContrast == obj.fContrast; } return false; } public override readonly bool Equals(object obj) { if (obj is SKHighContrastConfig obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKHighContrastConfig left, SKHighContrastConfig right) { return left.Equals(right); } public static bool operator !=(SKHighContrastConfig left, SKHighContrastConfig right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fGrayscale); hashCode.Add(fInvertStyle); hashCode.Add(fContrast); return hashCode.ToHashCode(); } } public struct SKPngEncoderOptions : IEquatable { public static readonly SKPngEncoderOptions Default; private SKPngEncoderFilterFlags fFilterFlags; private int fZLibLevel; private unsafe void* fComments; public SKPngEncoderFilterFlags FilterFlags { readonly get { return fFilterFlags; } set { fFilterFlags = value; } } public int ZLibLevel { readonly get { return fZLibLevel; } set { fZLibLevel = value; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public SKTransferFunctionBehavior UnpremulBehavior { readonly get { return SKTransferFunctionBehavior.Respect; } set { } } static SKPngEncoderOptions() { Default = new SKPngEncoderOptions(SKPngEncoderFilterFlags.AllFilters, 6); } public unsafe SKPngEncoderOptions(SKPngEncoderFilterFlags filterFlags, int zLibLevel) { fFilterFlags = filterFlags; fZLibLevel = zLibLevel; fComments = null; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Using SKPngEncoderOptions(SKPngEncoderFilterFlags, int) instead.")] public unsafe SKPngEncoderOptions(SKPngEncoderFilterFlags filterFlags, int zLibLevel, SKTransferFunctionBehavior unpremulBehavior) { fFilterFlags = filterFlags; fZLibLevel = zLibLevel; fComments = null; } public unsafe readonly bool Equals(SKPngEncoderOptions obj) { if (fFilterFlags == obj.fFilterFlags && fZLibLevel == obj.fZLibLevel) { return fComments == obj.fComments; } return false; } public override readonly bool Equals(object obj) { if (obj is SKPngEncoderOptions obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKPngEncoderOptions left, SKPngEncoderOptions right) { return left.Equals(right); } public static bool operator !=(SKPngEncoderOptions left, SKPngEncoderOptions right) { return !left.Equals(right); } public unsafe override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fFilterFlags); hashCode.Add(fZLibLevel); hashCode.Add(fComments); return hashCode.ToHashCode(); } } public struct SKJpegEncoderOptions : IEquatable { public static readonly SKJpegEncoderOptions Default; private int fQuality; private SKJpegEncoderDownsample fDownsample; private SKJpegEncoderAlphaOption fAlphaOption; [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public SKTransferFunctionBehavior BlendBehavior { readonly get { return SKTransferFunctionBehavior.Respect; } set { } } public int Quality { readonly get { return fQuality; } set { fQuality = value; } } public SKJpegEncoderDownsample Downsample { readonly get { return fDownsample; } set { fDownsample = value; } } public SKJpegEncoderAlphaOption AlphaOption { readonly get { return fAlphaOption; } set { fAlphaOption = value; } } static SKJpegEncoderOptions() { Default = new SKJpegEncoderOptions(100, SKJpegEncoderDownsample.Downsample420, SKJpegEncoderAlphaOption.Ignore); } public SKJpegEncoderOptions(int quality, SKJpegEncoderDownsample downsample, SKJpegEncoderAlphaOption alphaOption) { fQuality = quality; fDownsample = downsample; fAlphaOption = alphaOption; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKJpegEncoderOptions(int, SKJpegEncoderDownsample, SKJpegEncoderAlphaOption) instead.")] public SKJpegEncoderOptions(int quality, SKJpegEncoderDownsample downsample, SKJpegEncoderAlphaOption alphaOption, SKTransferFunctionBehavior blendBehavior) { fQuality = quality; fDownsample = downsample; fAlphaOption = alphaOption; } public readonly bool Equals(SKJpegEncoderOptions obj) { if (fQuality == obj.fQuality && fDownsample == obj.fDownsample) { return fAlphaOption == obj.fAlphaOption; } return false; } public override readonly bool Equals(object obj) { if (obj is SKJpegEncoderOptions obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKJpegEncoderOptions left, SKJpegEncoderOptions right) { return left.Equals(right); } public static bool operator !=(SKJpegEncoderOptions left, SKJpegEncoderOptions right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fQuality); hashCode.Add(fDownsample); hashCode.Add(fAlphaOption); return hashCode.ToHashCode(); } } public struct SKWebpEncoderOptions : IEquatable { public static readonly SKWebpEncoderOptions Default; private SKWebpEncoderCompression fCompression; private float fQuality; [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public SKTransferFunctionBehavior UnpremulBehavior { readonly get { return SKTransferFunctionBehavior.Respect; } set { } } public SKWebpEncoderCompression Compression { readonly get { return fCompression; } set { fCompression = value; } } public float Quality { readonly get { return fQuality; } set { fQuality = value; } } static SKWebpEncoderOptions() { Default = new SKWebpEncoderOptions(SKWebpEncoderCompression.Lossy, 100f); } public SKWebpEncoderOptions(SKWebpEncoderCompression compression, float quality) { fCompression = compression; fQuality = quality; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKWebpEncoderOptions(SKWebpEncoderCompression, float) instead.")] public SKWebpEncoderOptions(SKWebpEncoderCompression compression, float quality, SKTransferFunctionBehavior unpremulBehavior) { fCompression = compression; fQuality = quality; } public readonly bool Equals(SKWebpEncoderOptions obj) { if (fCompression == obj.fCompression) { return fQuality == obj.fQuality; } return false; } public override readonly bool Equals(object obj) { if (obj is SKWebpEncoderOptions obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKWebpEncoderOptions left, SKWebpEncoderOptions right) { return left.Equals(right); } public static bool operator !=(SKWebpEncoderOptions left, SKWebpEncoderOptions right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fCompression); hashCode.Add(fQuality); return hashCode.ToHashCode(); } } public delegate void SKBitmapReleaseDelegate(IntPtr address, object context); public delegate void SKDataReleaseDelegate(IntPtr address, object context); public delegate void SKImageRasterReleaseDelegate(IntPtr pixels, object context); public delegate void SKImageTextureReleaseDelegate(object context); public delegate void SKSurfaceReleaseDelegate(IntPtr address, object context); [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GRGlGetProcedureAddressDelegate instead.")] public delegate IntPtr GRGlGetProcDelegate(object context, string name); public delegate IntPtr GRGlGetProcedureAddressDelegate(string name); public delegate IntPtr GRVkGetProcedureAddressDelegate(string name, IntPtr instance, IntPtr device); public delegate void SKGlyphPathDelegate(SKPath path, SKMatrix matrix); public enum GRBackend { Metal, OpenGL, Vulkan, Dawn, Direct3D } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKColorType instead.")] public enum GRPixelConfig { Unknown, Alpha8, Gray8, Rgb565, Rgba4444, Rgba8888, Rgb888, Bgra8888, Srgba8888, [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The pixel configuration 'sBGRA 8888' is no longer supported in the native library.", true)] Sbgra8888, Rgba1010102, [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The pixel configuration 'floating-point RGBA' is no longer supported in the native library.", true)] RgbaFloat, [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The pixel configuration 'floating-point RG' is no longer supported in the native library.", true)] RgFloat, AlphaHalf, RgbaHalf, Alpha8AsAlpha, Alpha8AsRed, AlphaHalfAsLum, AlphaHalfAsRed, Gray8AsLum, Gray8AsRed, RgbaHalfClamped, Alpha16, Rg1616, Rgba16161616, RgHalf, Rg88, Rgb888x, RgbEtc1 } public class GRBackendRenderTarget : SKObject, ISKSkipObjectRegistration { public bool IsValid => SkiaApi.gr_backendrendertarget_is_valid(Handle); public int Width => SkiaApi.gr_backendrendertarget_get_width(Handle); public int Height => SkiaApi.gr_backendrendertarget_get_height(Handle); public int SampleCount => SkiaApi.gr_backendrendertarget_get_samples(Handle); public int StencilBits => SkiaApi.gr_backendrendertarget_get_stencils(Handle); public GRBackend Backend => SkiaApi.gr_backendrendertarget_get_backend(Handle).FromNative(); public SKSizeI Size => new SKSizeI(Width, Height); public SKRectI Rect => new SKRectI(0, 0, Width, Height); internal GRBackendRenderTarget(IntPtr handle, bool owns) : base(handle, owns) { } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GRBackendRenderTarget(int, int, int, int, GRGlFramebufferInfo) instead.")] public GRBackendRenderTarget(GRBackend backend, GRBackendRenderTargetDesc desc) : this(IntPtr.Zero, owns: true) { switch (backend) { case GRBackend.Metal: throw new NotSupportedException(); case GRBackend.OpenGL: CreateGl(glInfo: new GRGlFramebufferInfo((uint)(int)desc.RenderTargetHandle, desc.Config.ToGlSizedFormat()), width: desc.Width, height: desc.Height, sampleCount: desc.SampleCount, stencilBits: desc.StencilBits); break; case GRBackend.Vulkan: throw new NotSupportedException(); case GRBackend.Dawn: throw new NotSupportedException(); default: throw new ArgumentOutOfRangeException("backend"); } } public GRBackendRenderTarget(int width, int height, int sampleCount, int stencilBits, GRGlFramebufferInfo glInfo) : this(IntPtr.Zero, owns: true) { CreateGl(width, height, sampleCount, stencilBits, glInfo); } public GRBackendRenderTarget(int width, int height, int sampleCount, GRVkImageInfo vkImageInfo) : this(IntPtr.Zero, owns: true) { CreateVulkan(width, height, sampleCount, vkImageInfo); } private unsafe void CreateGl(int width, int height, int sampleCount, int stencilBits, GRGlFramebufferInfo glInfo) { Handle = SkiaApi.gr_backendrendertarget_new_gl(width, height, sampleCount, stencilBits, &glInfo); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new GRBackendRenderTarget instance."); } } private unsafe void CreateVulkan(int width, int height, int sampleCount, GRVkImageInfo vkImageInfo) { Handle = SkiaApi.gr_backendrendertarget_new_vulkan(width, height, sampleCount, &vkImageInfo); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new GRBackendRenderTarget instance."); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.gr_backendrendertarget_delete(Handle); } public GRGlFramebufferInfo GetGlFramebufferInfo() { if (!GetGlFramebufferInfo(out var glInfo)) { return default(GRGlFramebufferInfo); } return glInfo; } public unsafe bool GetGlFramebufferInfo(out GRGlFramebufferInfo glInfo) { fixed (GRGlFramebufferInfo* glInfo2 = &glInfo) { return SkiaApi.gr_backendrendertarget_get_gl_framebufferinfo(Handle, glInfo2); } } } public class GRBackendTexture : SKObject, ISKSkipObjectRegistration { [Obsolete] internal struct GRTextureInfoObsolete { public uint fTarget; public uint fID; } public bool IsValid => SkiaApi.gr_backendtexture_is_valid(Handle); public int Width => SkiaApi.gr_backendtexture_get_width(Handle); public int Height => SkiaApi.gr_backendtexture_get_height(Handle); public bool HasMipMaps => SkiaApi.gr_backendtexture_has_mipmaps(Handle); public GRBackend Backend => SkiaApi.gr_backendtexture_get_backend(Handle).FromNative(); public SKSizeI Size => new SKSizeI(Width, Height); public SKRectI Rect => new SKRectI(0, 0, Width, Height); internal GRBackendTexture(IntPtr handle, bool owns) : base(handle, owns) { } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GRBackendTexture(int, int, bool, GRGlTextureInfo) instead.")] public GRBackendTexture(GRGlBackendTextureDesc desc) : this(IntPtr.Zero, owns: true) { GRGlTextureInfo textureHandle = desc.TextureHandle; if (textureHandle.Format == 0) { textureHandle.Format = desc.Config.ToGlSizedFormat(); } CreateGl(desc.Width, desc.Height, mipmapped: false, textureHandle); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GRBackendTexture(int, int, bool, GRGlTextureInfo) instead.")] public GRBackendTexture(GRBackendTextureDesc desc) : this(IntPtr.Zero, owns: true) { IntPtr textureHandle = desc.TextureHandle; GRTextureInfoObsolete gRTextureInfoObsolete = Marshal.PtrToStructure(textureHandle); CreateGl(glInfo: new GRGlTextureInfo(gRTextureInfoObsolete.fTarget, gRTextureInfoObsolete.fID, desc.Config.ToGlSizedFormat()), width: desc.Width, height: desc.Height, mipmapped: false); } public GRBackendTexture(int width, int height, bool mipmapped, GRGlTextureInfo glInfo) : this(IntPtr.Zero, owns: true) { CreateGl(width, height, mipmapped, glInfo); } public GRBackendTexture(int width, int height, GRVkImageInfo vkInfo) : this(IntPtr.Zero, owns: true) { CreateVulkan(width, height, vkInfo); } private unsafe void CreateGl(int width, int height, bool mipmapped, GRGlTextureInfo glInfo) { Handle = SkiaApi.gr_backendtexture_new_gl(width, height, mipmapped, &glInfo); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new GRBackendTexture instance."); } } private unsafe void CreateVulkan(int width, int height, GRVkImageInfo vkInfo) { Handle = SkiaApi.gr_backendtexture_new_vulkan(width, height, &vkInfo); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new GRBackendTexture instance."); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.gr_backendtexture_delete(Handle); } public GRGlTextureInfo GetGlTextureInfo() { if (!GetGlTextureInfo(out var glInfo)) { return default(GRGlTextureInfo); } return glInfo; } public unsafe bool GetGlTextureInfo(out GRGlTextureInfo glInfo) { fixed (GRGlTextureInfo* glInfo2 = &glInfo) { return SkiaApi.gr_backendtexture_get_gl_textureinfo(Handle, glInfo2); } } } public class GRContext : GRRecordingContext { public new GRBackend Backend => base.Backend; public bool IsAbandoned => SkiaApi.gr_direct_context_is_abandoned(Handle); internal GRContext(IntPtr h, bool owns) : base(h, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { AbandonContext(); base.DisposeNative(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateGl() instead.")] public static GRContext Create(GRBackend backend) { return backend switch { GRBackend.Metal => throw new NotSupportedException(), GRBackend.OpenGL => CreateGl(), GRBackend.Vulkan => throw new NotSupportedException(), GRBackend.Dawn => throw new NotSupportedException(), _ => throw new ArgumentOutOfRangeException("backend"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateGl(GRGlInterface) instead.")] public static GRContext Create(GRBackend backend, GRGlInterface backendContext) { return backend switch { GRBackend.Metal => throw new NotSupportedException(), GRBackend.OpenGL => CreateGl(backendContext), GRBackend.Vulkan => throw new NotSupportedException(), GRBackend.Dawn => throw new NotSupportedException(), _ => throw new ArgumentOutOfRangeException("backend"), }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateGl(GRGlInterface) instead.")] public static GRContext Create(GRBackend backend, IntPtr backendContext) { return backend switch { GRBackend.Metal => throw new NotSupportedException(), GRBackend.OpenGL => GetObject(SkiaApi.gr_direct_context_make_gl(backendContext)), GRBackend.Vulkan => throw new NotSupportedException(), GRBackend.Dawn => throw new NotSupportedException(), _ => throw new ArgumentOutOfRangeException("backend"), }; } public static GRContext CreateGl() { return CreateGl(null, null); } public static GRContext CreateGl(GRGlInterface backendContext) { return CreateGl(backendContext, null); } public static GRContext CreateGl(GRContextOptions options) { return CreateGl(null, options); } public unsafe static GRContext CreateGl(GRGlInterface backendContext, GRContextOptions options) { IntPtr glInterface = backendContext?.Handle ?? IntPtr.Zero; if (options == null) { return GetObject(SkiaApi.gr_direct_context_make_gl(glInterface)); } GRContextOptionsNative gRContextOptionsNative = options.ToNative(); return GetObject(SkiaApi.gr_direct_context_make_gl_with_options(glInterface, &gRContextOptionsNative)); } public static GRContext CreateVulkan(GRVkBackendContext backendContext) { return CreateVulkan(backendContext, null); } public unsafe static GRContext CreateVulkan(GRVkBackendContext backendContext, GRContextOptions options) { if (backendContext == null) { throw new ArgumentNullException("backendContext"); } if (options == null) { return GetObject(SkiaApi.gr_direct_context_make_vulkan(backendContext.ToNative())); } GRContextOptionsNative gRContextOptionsNative = options.ToNative(); return GetObject(SkiaApi.gr_direct_context_make_vulkan_with_options(backendContext.ToNative(), &gRContextOptionsNative)); } public void AbandonContext(bool releaseResources = false) { if (releaseResources) { SkiaApi.gr_direct_context_release_resources_and_abandon_context(Handle); } else { SkiaApi.gr_direct_context_abandon_context(Handle); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetResourceCacheLimit() instead.")] public void GetResourceCacheLimits(out int maxResources, out long maxResourceBytes) { maxResources = -1; maxResourceBytes = GetResourceCacheLimit(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SetResourceCacheLimit(long) instead.")] public void SetResourceCacheLimits(int maxResources, long maxResourceBytes) { SetResourceCacheLimit(maxResourceBytes); } public long GetResourceCacheLimit() { return (long)SkiaApi.gr_direct_context_get_resource_cache_limit(Handle); } public void SetResourceCacheLimit(long maxResourceBytes) { SkiaApi.gr_direct_context_set_resource_cache_limit(Handle, (IntPtr)maxResourceBytes); } public unsafe void GetResourceCacheUsage(out int maxResources, out long maxResourceBytes) { IntPtr intPtr = default(IntPtr); fixed (int* maxResources2 = &maxResources) { SkiaApi.gr_direct_context_get_resource_cache_usage(Handle, maxResources2, &intPtr); } maxResourceBytes = (long)intPtr; } public void ResetContext(GRGlBackendState state) { ResetContext((uint)state); } public void ResetContext(GRBackendState state = GRBackendState.All) { ResetContext((uint)state); } public void ResetContext(uint state) { SkiaApi.gr_direct_context_reset_context(Handle, state); } public void Flush() { Flush(submit: true); } public void Flush(bool submit, bool synchronous = false) { if (submit) { SkiaApi.gr_direct_context_flush_and_submit(Handle, synchronous); } else { SkiaApi.gr_direct_context_flush(Handle); } } public void Submit(bool synchronous = false) { SkiaApi.gr_direct_context_submit(Handle, synchronous); } public new int GetMaxSurfaceSampleCount(SKColorType colorType) { return base.GetMaxSurfaceSampleCount(colorType); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public int GetRecommendedSampleCount(GRPixelConfig config, float dpi) { return 0; } public void DumpMemoryStatistics(SKTraceMemoryDump dump) { IntPtr handle = Handle; if (dump == null) { throw new ArgumentNullException("dump"); } SkiaApi.gr_direct_context_dump_memory_statistics(handle, dump.Handle); } public void PurgeResources() { SkiaApi.gr_direct_context_free_gpu_resources(Handle); } public void PurgeUnusedResources(long milliseconds) { SkiaApi.gr_direct_context_perform_deferred_cleanup(Handle, milliseconds); } public void PurgeUnlockedResources(bool scratchResourcesOnly) { SkiaApi.gr_direct_context_purge_unlocked_resources(Handle, scratchResourcesOnly); } public void PurgeUnlockedResources(long bytesToPurge, bool preferScratchResources) { SkiaApi.gr_direct_context_purge_unlocked_resources_bytes(Handle, (IntPtr)bytesToPurge, preferScratchResources); } internal static GRContext GetObject(IntPtr handle, bool owns = true) { return SKObject.GetOrAddObject(handle, owns, (IntPtr h, bool o) => new GRContext(h, o)); } } public class GRContextOptions { public bool AvoidStencilBuffers { get; set; } public int RuntimeProgramCacheSize { get; set; } = 256; public int GlyphCacheTextureMaximumBytes { get; set; } = 8388608; public bool AllowPathMaskCaching { get; set; } = true; public bool DoManualMipmapping { get; set; } public int BufferMapThreshold { get; set; } = -1; internal GRContextOptionsNative ToNative() { return new GRContextOptionsNative { fAllowPathMaskCaching = (AllowPathMaskCaching ? ((byte)1) : ((byte)0)), fAvoidStencilBuffers = (AvoidStencilBuffers ? ((byte)1) : ((byte)0)), fBufferMapThreshold = BufferMapThreshold, fDoManualMipmapping = (DoManualMipmapping ? ((byte)1) : ((byte)0)), fGlyphCacheTextureMaximumBytes = (IntPtr)GlyphCacheTextureMaximumBytes, fRuntimeProgramCacheSize = RuntimeProgramCacheSize }; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GRBackendRenderTarget instead.")] public struct GRBackendRenderTargetDesc : IEquatable { public int Width { get; set; } public int Height { get; set; } public GRPixelConfig Config { get; set; } public GRSurfaceOrigin Origin { get; set; } public int SampleCount { get; set; } public int StencilBits { get; set; } public IntPtr RenderTargetHandle { get; set; } public readonly SKSizeI Size => new SKSizeI(Width, Height); public readonly SKRectI Rect => new SKRectI(0, 0, Width, Height); public readonly bool Equals(GRBackendRenderTargetDesc obj) { if (Width == obj.Width && Height == obj.Height && Config == obj.Config && Origin == obj.Origin && SampleCount == obj.SampleCount && StencilBits == obj.StencilBits) { return RenderTargetHandle == obj.RenderTargetHandle; } return false; } public override readonly bool Equals(object obj) { if (obj is GRBackendRenderTargetDesc obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRBackendRenderTargetDesc left, GRBackendRenderTargetDesc right) { return left.Equals(right); } public static bool operator !=(GRBackendRenderTargetDesc left, GRBackendRenderTargetDesc right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(Width); hashCode.Add(Height); hashCode.Add(Config); hashCode.Add(Origin); hashCode.Add(SampleCount); hashCode.Add(StencilBits); hashCode.Add(RenderTargetHandle); return hashCode.ToHashCode(); } } [Flags] public enum GRGlBackendState : uint { None = 0u, RenderTarget = 1u, TextureBinding = 2u, View = 4u, Blend = 8u, MSAAEnable = 0x10u, Vertex = 0x20u, Stencil = 0x40u, PixelStore = 0x80u, Program = 0x100u, FixedFunction = 0x200u, Misc = 0x400u, PathRendering = 0x800u, All = 0xFFFFu } [Flags] public enum GRBackendState : uint { None = 0u, All = uint.MaxValue } public struct GRGlFramebufferInfo : IEquatable { private uint fFBOID; private uint fFormat; public uint FramebufferObjectId { readonly get { return fFBOID; } set { fFBOID = value; } } public uint Format { readonly get { return fFormat; } set { fFormat = value; } } public GRGlFramebufferInfo(uint fboId) { fFBOID = fboId; fFormat = 0u; } public GRGlFramebufferInfo(uint fboId, uint format) { fFBOID = fboId; fFormat = format; } public readonly bool Equals(GRGlFramebufferInfo obj) { if (fFBOID == obj.fFBOID) { return fFormat == obj.fFormat; } return false; } public override readonly bool Equals(object obj) { if (obj is GRGlFramebufferInfo obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRGlFramebufferInfo left, GRGlFramebufferInfo right) { return left.Equals(right); } public static bool operator !=(GRGlFramebufferInfo left, GRGlFramebufferInfo right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fFBOID); hashCode.Add(fFormat); return hashCode.ToHashCode(); } } public struct GRGlTextureInfo : IEquatable { private uint fTarget; private uint fID; private uint fFormat; public uint Target { readonly get { return fTarget; } set { fTarget = value; } } public uint Id { readonly get { return fID; } set { fID = value; } } public uint Format { readonly get { return fFormat; } set { fFormat = value; } } public GRGlTextureInfo(uint target, uint id) { fTarget = target; fID = id; fFormat = 0u; } public GRGlTextureInfo(uint target, uint id, uint format) { fTarget = target; fID = id; fFormat = format; } public readonly bool Equals(GRGlTextureInfo obj) { if (fTarget == obj.fTarget && fID == obj.fID) { return fFormat == obj.fFormat; } return false; } public override readonly bool Equals(object obj) { if (obj is GRGlTextureInfo obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRGlTextureInfo left, GRGlTextureInfo right) { return left.Equals(right); } public static bool operator !=(GRGlTextureInfo left, GRGlTextureInfo right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fTarget); hashCode.Add(fID); hashCode.Add(fFormat); return hashCode.ToHashCode(); } } [EditorBrowsable(EditorBrowsableState.Never)] [Flags] [Obsolete] public enum GRBackendTextureDescFlags { None = 0, RenderTarget = 1 } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GRBackendTexture instead.")] public struct GRBackendTextureDesc : IEquatable { public GRBackendTextureDescFlags Flags { get; set; } public GRSurfaceOrigin Origin { get; set; } public int Width { get; set; } public int Height { get; set; } public GRPixelConfig Config { get; set; } public int SampleCount { get; set; } public IntPtr TextureHandle { get; set; } public readonly SKSizeI Size => new SKSizeI(Width, Height); public readonly SKRectI Rect => new SKRectI(0, 0, Width, Height); public readonly bool Equals(GRBackendTextureDesc obj) { if (Flags == obj.Flags && Origin == obj.Origin && Width == obj.Width && Height == obj.Height && Config == obj.Config && SampleCount == obj.SampleCount) { return TextureHandle == obj.TextureHandle; } return false; } public override readonly bool Equals(object obj) { if (obj is GRBackendTextureDesc obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRBackendTextureDesc left, GRBackendTextureDesc right) { return left.Equals(right); } public static bool operator !=(GRBackendTextureDesc left, GRBackendTextureDesc right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(Flags); hashCode.Add(Origin); hashCode.Add(Width); hashCode.Add(Height); hashCode.Add(Config); hashCode.Add(SampleCount); hashCode.Add(TextureHandle); return hashCode.ToHashCode(); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GRBackendTexture instead.")] public struct GRGlBackendTextureDesc : IEquatable { public GRBackendTextureDescFlags Flags { get; set; } public GRSurfaceOrigin Origin { get; set; } public int Width { get; set; } public int Height { get; set; } public GRPixelConfig Config { get; set; } public int SampleCount { get; set; } public GRGlTextureInfo TextureHandle { get; set; } public readonly SKSizeI Size => new SKSizeI(Width, Height); public readonly SKRectI Rect => new SKRectI(0, 0, Width, Height); public readonly bool Equals(GRGlBackendTextureDesc obj) { if (Flags == obj.Flags && Origin == obj.Origin && Width == obj.Width && Height == obj.Height && Config == obj.Config && SampleCount == obj.SampleCount) { return TextureHandle == obj.TextureHandle; } return false; } public override readonly bool Equals(object obj) { if (obj is GRGlBackendTextureDesc obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRGlBackendTextureDesc left, GRGlBackendTextureDesc right) { return left.Equals(right); } public static bool operator !=(GRGlBackendTextureDesc left, GRGlBackendTextureDesc right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(Flags); hashCode.Add(Origin); hashCode.Add(Width); hashCode.Add(Height); hashCode.Add(Config); hashCode.Add(SampleCount); hashCode.Add(TextureHandle); return hashCode.ToHashCode(); } } internal static class GRGlSizedFormat { internal const uint STENCIL_INDEX = 6401u; internal const uint DEPTH_COMPONENT = 6402u; internal const uint DEPTH_STENCIL = 34041u; internal const uint RED = 6403u; internal const uint RED_INTEGER = 36244u; internal const uint GREEN = 6404u; internal const uint BLUE = 6405u; internal const uint ALPHA = 6406u; internal const uint LUMINANCE = 6409u; internal const uint LUMINANCE_ALPHA = 6410u; internal const uint RG_INTEGER = 33320u; internal const uint RGB = 6407u; internal const uint RGB_INTEGER = 36248u; internal const uint SRGB = 35904u; internal const uint RGBA = 6408u; internal const uint RG = 33319u; internal const uint SRGB_ALPHA = 35906u; internal const uint RGBA_INTEGER = 36249u; internal const uint BGRA = 32993u; internal const uint STENCIL_INDEX4 = 36167u; internal const uint STENCIL_INDEX8 = 36168u; internal const uint STENCIL_INDEX16 = 36169u; internal const uint DEPTH_COMPONENT16 = 33189u; internal const uint DEPTH24_STENCIL8 = 35056u; internal const uint R8 = 33321u; internal const uint R16 = 33322u; internal const uint R16F = 33325u; internal const uint R32F = 33326u; internal const uint R8I = 33329u; internal const uint R8UI = 33330u; internal const uint R16I = 33331u; internal const uint R16UI = 33332u; internal const uint R32I = 33333u; internal const uint R32UI = 33334u; internal const uint LUMINANCE8 = 32832u; internal const uint LUMINANCE16F = 34846u; internal const uint ALPHA8 = 32828u; internal const uint ALPHA16 = 32830u; internal const uint ALPHA16F = 34844u; internal const uint ALPHA32F = 34838u; internal const uint ALPHA8I = 36240u; internal const uint ALPHA8UI = 36222u; internal const uint ALPHA16I = 36234u; internal const uint ALPHA16UI = 36216u; internal const uint ALPHA32I = 36228u; internal const uint ALPHA32UI = 36210u; internal const uint RG8 = 33323u; internal const uint RG16 = 33324u; internal const uint RG16F = 33327u; internal const uint RG8I = 33335u; internal const uint RG8UI = 33336u; internal const uint RG16I = 33337u; internal const uint RG16UI = 33338u; internal const uint RG32I = 33339u; internal const uint RG32UI = 33340u; internal const uint RGB5 = 32848u; internal const uint RGB565 = 36194u; internal const uint RGB8 = 32849u; internal const uint SRGB8 = 35905u; internal const uint RGB8I = 36239u; internal const uint RGB8UI = 36221u; internal const uint RGB16I = 36233u; internal const uint RGB16UI = 36215u; internal const uint RGB32I = 36227u; internal const uint RGB32UI = 36209u; internal const uint RGBA4 = 32854u; internal const uint RGB5_A1 = 32855u; internal const uint RGBA8 = 32856u; internal const uint RGB10_A2 = 32857u; internal const uint SRGB8_ALPHA8 = 35907u; internal const uint RGBA16F = 34842u; internal const uint RGBA32F = 34836u; internal const uint RG32F = 33328u; internal const uint RGBA16 = 32859u; internal const uint RGBA8I = 36238u; internal const uint RGBA8UI = 36220u; internal const uint RGBA16I = 36232u; internal const uint RGBA16UI = 36214u; internal const uint RGBA32I = 36226u; internal const uint RGBA32UI = 36208u; internal const uint BGRA8 = 37793u; internal const uint COMPRESSED_ETC1_RGB8 = 36196u; } public class GRGlInterface : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration { private static class AngleLoader { private static readonly IntPtr libEGL; private static readonly IntPtr libGLESv2; public static bool IsValid { get { if (libEGL != IntPtr.Zero) { return libGLESv2 != IntPtr.Zero; } return false; } } [DllImport("Kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); [DllImport("Kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] private static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); [DllImport("libEGL.dll")] private static extern IntPtr eglGetProcAddress([MarshalAs(UnmanagedType.LPStr)] string procname); static AngleLoader() { if (PlatformConfiguration.IsWindows) { libEGL = LoadLibrary("libEGL.dll"); libGLESv2 = LoadLibrary("libGLESv2.dll"); } } public static IntPtr GetProc(string name) { if (!PlatformConfiguration.IsWindows) { return IntPtr.Zero; } if (!IsValid) { return IntPtr.Zero; } IntPtr intPtr = GetProcAddress(libGLESv2, name); if (intPtr == IntPtr.Zero) { intPtr = GetProcAddress(libEGL, name); } if (intPtr == IntPtr.Zero) { intPtr = eglGetProcAddress(name); } return intPtr; } } internal GRGlInterface(IntPtr h, bool owns) : base(h, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public static GRGlInterface Create() { return CreateGl() ?? CreateAngle(); } private static GRGlInterface CreateGl() { return GetObject(SkiaApi.gr_glinterface_create_native_interface()); } public static GRGlInterface CreateAngle() { if (PlatformConfiguration.IsWindows) { return CreateAngle(AngleLoader.GetProc); } return null; } public unsafe static GRGlInterface Create(GRGlGetProcedureAddressDelegate get) { GCHandle gch; IntPtr contextPtr; GRGlGetProcProxyDelegate get2 = DelegateProxies.Create(get, DelegateProxies.GRGlGetProcDelegateProxy, out gch, out contextPtr); try { return GetObject(SkiaApi.gr_glinterface_assemble_interface((void*)contextPtr, get2)); } finally { gch.Free(); } } public static GRGlInterface CreateAngle(GRGlGetProcedureAddressDelegate get) { return CreateGles(get); } public unsafe static GRGlInterface CreateOpenGl(GRGlGetProcedureAddressDelegate get) { GCHandle gch; IntPtr contextPtr; GRGlGetProcProxyDelegate get2 = DelegateProxies.Create(get, DelegateProxies.GRGlGetProcDelegateProxy, out gch, out contextPtr); try { return GetObject(SkiaApi.gr_glinterface_assemble_gl_interface((void*)contextPtr, get2)); } finally { gch.Free(); } } public unsafe static GRGlInterface CreateGles(GRGlGetProcedureAddressDelegate get) { GCHandle gch; IntPtr contextPtr; GRGlGetProcProxyDelegate get2 = DelegateProxies.Create(get, DelegateProxies.GRGlGetProcDelegateProxy, out gch, out contextPtr); try { return GetObject(SkiaApi.gr_glinterface_assemble_gles_interface((void*)contextPtr, get2)); } finally { gch.Free(); } } public unsafe static GRGlInterface CreateWebGl(GRGlGetProcedureAddressDelegate get) { GCHandle gch; IntPtr contextPtr; GRGlGetProcProxyDelegate get2 = DelegateProxies.Create(get, DelegateProxies.GRGlGetProcDelegateProxy, out gch, out contextPtr); try { return GetObject(SkiaApi.gr_glinterface_assemble_webgl_interface((void*)contextPtr, get2)); } finally { gch.Free(); } } public static GRGlInterface CreateEvas(IntPtr evas) { return null; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create() instead.")] public static GRGlInterface CreateDefaultInterface() { return Create(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create() instead.")] public static GRGlInterface CreateNativeGlInterface() { return CreateGl(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create() instead.")] public static GRGlInterface CreateNativeAngleInterface() { return CreateAngle(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateEvas(IntPtr) instead.")] public static GRGlInterface CreateNativeEvasInterface(IntPtr evas) { return CreateEvas(evas); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRGlGetProcedureAddressDelegate) instead.")] public static GRGlInterface AssembleInterface(GRGlGetProcDelegate get) { return Create((string name) => get(null, name)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRGlGetProcedureAddressDelegate) instead.")] public static GRGlInterface AssembleInterface(object context, GRGlGetProcDelegate get) { return Create((string name) => get(context, name)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateAngle(GRGlGetProcedureAddressDelegate) instead.")] public static GRGlInterface AssembleAngleInterface(GRGlGetProcDelegate get) { return CreateAngle((string name) => get(null, name)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateAngle(GRGlGetProcedureAddressDelegate) instead.")] public static GRGlInterface AssembleAngleInterface(object context, GRGlGetProcDelegate get) { return CreateAngle((string name) => get(context, name)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateOpenGl(GRGlGetProcedureAddressDelegate) instead.")] public static GRGlInterface AssembleGlInterface(GRGlGetProcDelegate get) { return CreateOpenGl((string name) => get(null, name)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateOpenGl(GRGlGetProcedureAddressDelegate) instead.")] public static GRGlInterface AssembleGlInterface(object context, GRGlGetProcDelegate get) { return CreateOpenGl((string name) => get(context, name)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateGles(GRGlGetProcedureAddressDelegate) instead.")] public static GRGlInterface AssembleGlesInterface(GRGlGetProcDelegate get) { return CreateGles((string name) => get(null, name)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateGles(GRGlGetProcedureAddressDelegate) instead.")] public static GRGlInterface AssembleGlesInterface(object context, GRGlGetProcDelegate get) { return CreateGles((string name) => get(context, name)); } public bool Validate() { return SkiaApi.gr_glinterface_validate(Handle); } public bool HasExtension(string extension) { return SkiaApi.gr_glinterface_has_extension(Handle, extension); } internal static GRGlInterface GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new GRGlInterface(handle, owns: true); } return null; } } public class GRRecordingContext : SKObject, ISKReferenceCounted { public GRBackend Backend => SkiaApi.gr_recording_context_get_backend(Handle).FromNative(); internal GRRecordingContext(IntPtr h, bool owns) : base(h, owns) { } public int GetMaxSurfaceSampleCount(SKColorType colorType) { return SkiaApi.gr_recording_context_get_max_surface_sample_count_for_color_type(Handle, colorType.ToNative()); } internal static GRRecordingContext GetObject(IntPtr handle, bool owns = true, bool unrefExisting = true) { return SKObject.GetOrAddObject(handle, owns, unrefExisting, (IntPtr h, bool o) => new GRRecordingContext(h, o)); } } public class GRVkBackendContext : IDisposable { private GRVkGetProcedureAddressDelegate getProc; private GRVkGetProcProxyDelegate getProcProxy; private GCHandle getProcHandle; private unsafe void* getProcContext; public IntPtr VkInstance { get; set; } public IntPtr VkPhysicalDevice { get; set; } public IntPtr VkDevice { get; set; } public IntPtr VkQueue { get; set; } public uint GraphicsQueueIndex { get; set; } public uint MaxAPIVersion { get; set; } public GRVkExtensions Extensions { get; set; } public IntPtr VkPhysicalDeviceFeatures { get; set; } public IntPtr VkPhysicalDeviceFeatures2 { get; set; } public unsafe GRVkGetProcedureAddressDelegate GetProcedureAddress { get { return getProc; } set { getProc = value; if (getProcHandle.IsAllocated) { getProcHandle.Free(); } getProcProxy = null; getProcHandle = default(GCHandle); getProcContext = null; if (value != null) { getProcProxy = DelegateProxies.Create(value, DelegateProxies.GRVkGetProcDelegateProxy, out var gch, out var contextPtr); getProcHandle = gch; getProcContext = (void*)contextPtr; } } } public bool ProtectedContext { get; set; } protected virtual void Dispose(bool disposing) { if (disposing && getProcHandle.IsAllocated) { getProcHandle.Free(); getProcHandle = default(GCHandle); } } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } internal unsafe GRVkBackendContextNative ToNative() { return new GRVkBackendContextNative { fInstance = VkInstance, fDevice = VkDevice, fPhysicalDevice = VkPhysicalDevice, fQueue = VkQueue, fGraphicsQueueIndex = GraphicsQueueIndex, fMaxAPIVersion = MaxAPIVersion, fVkExtensions = (Extensions?.Handle ?? IntPtr.Zero), fDeviceFeatures = VkPhysicalDeviceFeatures, fDeviceFeatures2 = VkPhysicalDeviceFeatures2, fGetProcUserData = getProcContext, fGetProc = getProcProxy, fProtectedContext = (ProtectedContext ? ((byte)1) : ((byte)0)) }; } } public class GRVkExtensions : SKObject, ISKSkipObjectRegistration { internal GRVkExtensions(IntPtr h, bool owns) : base(h, owns) { } private GRVkExtensions() : this(SkiaApi.gr_vk_extensions_new(), owns: true) { } protected override void DisposeNative() { SkiaApi.gr_vk_extensions_delete(Handle); } public void HasExtension(string extension, int minVersion) { SkiaApi.gr_vk_extensions_has_extension(Handle, extension, (uint)minVersion); } public void Initialize(GRVkGetProcedureAddressDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice) { Initialize(getProc, vkInstance, vkPhysicalDevice, null, null); } public unsafe void Initialize(GRVkGetProcedureAddressDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice, string[] instanceExtensions, string[] deviceExtensions) { GCHandle gch; IntPtr contextPtr; GRVkGetProcProxyDelegate getProc2 = DelegateProxies.Create(getProc, DelegateProxies.GRVkGetProcDelegateProxy, out gch, out contextPtr); try { SkiaApi.gr_vk_extensions_init(Handle, getProc2, (void*)contextPtr, vkInstance, vkPhysicalDevice, (instanceExtensions != null) ? ((uint)instanceExtensions.Length) : 0u, instanceExtensions, (deviceExtensions != null) ? ((uint)deviceExtensions.Length) : 0u, deviceExtensions); } finally { gch.Free(); } } public static GRVkExtensions Create(GRVkGetProcedureAddressDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice, string[] instanceExtensions, string[] deviceExtensions) { GRVkExtensions gRVkExtensions = new GRVkExtensions(); gRVkExtensions.Initialize(getProc, vkInstance, vkPhysicalDevice, instanceExtensions, deviceExtensions); return gRVkExtensions; } internal static GRVkExtensions GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new GRVkExtensions(handle, owns: true); } return null; } } internal static class HandleDictionary { private static readonly Type SkipObjectRegistrationType = typeof(ISKSkipObjectRegistration); internal static readonly Dictionary instances = new Dictionary(); internal static readonly IPlatformLock instancesLock = PlatformLock.Create(); internal static bool GetInstance(IntPtr handle, out TSkiaObject instance) where TSkiaObject : SKObject { if (handle == IntPtr.Zero) { instance = null; return false; } if (SkipObjectRegistrationType.IsAssignableFrom(typeof(TSkiaObject))) { instance = null; return false; } instancesLock.EnterReadLock(); try { return GetInstanceNoLocks(handle, out instance); } finally { instancesLock.ExitReadLock(); } } internal static TSkiaObject GetOrAddObject(IntPtr handle, bool owns, bool unrefExisting, Func objectFactory) where TSkiaObject : SKObject { if (handle == IntPtr.Zero) { return null; } if (SkipObjectRegistrationType.IsAssignableFrom(typeof(TSkiaObject))) { return objectFactory(handle, owns); } instancesLock.EnterUpgradeableReadLock(); try { if (GetInstanceNoLocks(handle, out var instance)) { if (unrefExisting && instance is ISKReferenceCounted obj) { obj.SafeUnRef(); } return instance; } return objectFactory(handle, owns); } finally { instancesLock.ExitUpgradeableReadLock(); } } private static bool GetInstanceNoLocks(IntPtr handle, out TSkiaObject instance) where TSkiaObject : SKObject { if (instances.TryGetValue(handle, out var value) && value.IsAlive && value.Target is TSkiaObject val && !val.IsDisposed) { instance = val; return true; } instance = null; return false; } internal static void RegisterHandle(IntPtr handle, SKObject instance) { if (handle == IntPtr.Zero || instance == null || instance is ISKSkipObjectRegistration) { return; } SKObject sKObject = null; instancesLock.EnterWriteLock(); try { if (instances.TryGetValue(handle, out var value) && value.Target is SKObject { IsDisposed: false } sKObject2) { sKObject = sKObject2; } instances[handle] = new WeakReference(instance); } finally { instancesLock.ExitWriteLock(); } sKObject?.DisposeInternal(); } internal static void DeregisterHandle(IntPtr handle, SKObject instance) { if (handle == IntPtr.Zero || instance is ISKSkipObjectRegistration) { return; } instancesLock.EnterWriteLock(); try { if (instances.TryGetValue(handle, out var value) && (!value.IsAlive || value.Target == instance)) { instances.Remove(handle); } } finally { instancesLock.ExitWriteLock(); } } } public struct SKPoint : IEquatable { public static readonly SKPoint Empty; private float x; private float y; public readonly bool IsEmpty => this == Empty; public readonly float Length => (float)Math.Sqrt(x * x + y * y); public readonly float LengthSquared => x * x + y * y; public float X { readonly get { return x; } set { x = value; } } public float Y { readonly get { return y; } set { y = value; } } public SKPoint(float x, float y) { this.x = x; this.y = y; } public void Offset(SKPoint p) { x += p.x; y += p.y; } public void Offset(float dx, float dy) { x += dx; y += dy; } public override readonly string ToString() { return $"{{X={x}, Y={y}}}"; } public static SKPoint Normalize(SKPoint point) { float num = point.x * point.x + point.y * point.y; double num2 = 1.0 / Math.Sqrt(num); return new SKPoint((float)((double)point.x * num2), (float)((double)point.y * num2)); } public static float Distance(SKPoint point, SKPoint other) { float num = point.x - other.x; float num2 = point.y - other.y; float num3 = num * num + num2 * num2; return (float)Math.Sqrt(num3); } public static float DistanceSquared(SKPoint point, SKPoint other) { float num = point.x - other.x; float num2 = point.y - other.y; return num * num + num2 * num2; } public static SKPoint Reflect(SKPoint point, SKPoint normal) { float num = point.x * point.x + point.y * point.y; return new SKPoint(point.x - 2f * num * normal.x, point.y - 2f * num * normal.y); } public static SKPoint Add(SKPoint pt, SKSizeI sz) { return pt + sz; } public static SKPoint Add(SKPoint pt, SKSize sz) { return pt + sz; } public static SKPoint Add(SKPoint pt, SKPointI sz) { return pt + sz; } public static SKPoint Add(SKPoint pt, SKPoint sz) { return pt + sz; } public static SKPoint Subtract(SKPoint pt, SKSizeI sz) { return pt - sz; } public static SKPoint Subtract(SKPoint pt, SKSize sz) { return pt - sz; } public static SKPoint Subtract(SKPoint pt, SKPointI sz) { return pt - sz; } public static SKPoint Subtract(SKPoint pt, SKPoint sz) { return pt - sz; } public static SKPoint operator +(SKPoint pt, SKSizeI sz) { return new SKPoint(pt.x + (float)sz.Width, pt.y + (float)sz.Height); } public static SKPoint operator +(SKPoint pt, SKSize sz) { return new SKPoint(pt.x + sz.Width, pt.y + sz.Height); } public static SKPoint operator +(SKPoint pt, SKPointI sz) { return new SKPoint(pt.x + (float)sz.X, pt.y + (float)sz.Y); } public static SKPoint operator +(SKPoint pt, SKPoint sz) { return new SKPoint(pt.x + sz.X, pt.y + sz.Y); } public static SKPoint operator -(SKPoint pt, SKSizeI sz) { return new SKPoint(pt.X - (float)sz.Width, pt.Y - (float)sz.Height); } public static SKPoint operator -(SKPoint pt, SKSize sz) { return new SKPoint(pt.X - sz.Width, pt.Y - sz.Height); } public static SKPoint operator -(SKPoint pt, SKPointI sz) { return new SKPoint(pt.X - (float)sz.X, pt.Y - (float)sz.Y); } public static SKPoint operator -(SKPoint pt, SKPoint sz) { return new SKPoint(pt.X - sz.X, pt.Y - sz.Y); } public readonly bool Equals(SKPoint obj) { if (x == obj.x) { return y == obj.y; } return false; } public override readonly bool Equals(object obj) { if (obj is SKPoint obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKPoint left, SKPoint right) { return left.Equals(right); } public static bool operator !=(SKPoint left, SKPoint right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(x); hashCode.Add(y); return hashCode.ToHashCode(); } } public struct SKPointI : IEquatable { public static readonly SKPointI Empty; private int x; private int y; public readonly bool IsEmpty => this == Empty; public readonly int Length => (int)Math.Sqrt(x * x + y * y); public readonly int LengthSquared => x * x + y * y; public int X { readonly get { return x; } set { x = value; } } public int Y { readonly get { return y; } set { y = value; } } public SKPointI(SKSizeI sz) { x = sz.Width; y = sz.Height; } public SKPointI(int x, int y) { this.x = x; this.y = y; } public void Offset(SKPointI p) { x += p.X; y += p.Y; } public void Offset(int dx, int dy) { x += dx; y += dy; } public override readonly string ToString() { return $"{{X={x},Y={y}}}"; } public static SKPointI Normalize(SKPointI point) { int num = point.x * point.x + point.y * point.y; double num2 = 1.0 / Math.Sqrt(num); return new SKPointI((int)((double)point.x * num2), (int)((double)point.y * num2)); } public static float Distance(SKPointI point, SKPointI other) { int num = point.x - other.x; int num2 = point.y - other.y; int num3 = num * num + num2 * num2; return (float)Math.Sqrt(num3); } public static float DistanceSquared(SKPointI point, SKPointI other) { int num = point.x - other.x; int num2 = point.y - other.y; return num * num + num2 * num2; } public static SKPointI Reflect(SKPointI point, SKPointI normal) { int num = point.x * point.x + point.y * point.y; return new SKPointI((int)((float)point.x - 2f * (float)num * (float)normal.x), (int)((float)point.y - 2f * (float)num * (float)normal.y)); } public static SKPointI Ceiling(SKPoint value) { checked { int num = (int)Math.Ceiling(value.X); int num2 = (int)Math.Ceiling(value.Y); return new SKPointI(num, num2); } } public static SKPointI Round(SKPoint value) { checked { int num = (int)Math.Round(value.X); int num2 = (int)Math.Round(value.Y); return new SKPointI(num, num2); } } public static SKPointI Truncate(SKPoint value) { checked { int num = (int)value.X; int num2 = (int)value.Y; return new SKPointI(num, num2); } } public static SKPointI Add(SKPointI pt, SKSizeI sz) { return pt + sz; } public static SKPointI Add(SKPointI pt, SKPointI sz) { return pt + sz; } public static SKPointI Subtract(SKPointI pt, SKSizeI sz) { return pt - sz; } public static SKPointI Subtract(SKPointI pt, SKPointI sz) { return pt - sz; } public static SKPointI operator +(SKPointI pt, SKSizeI sz) { return new SKPointI(pt.X + sz.Width, pt.Y + sz.Height); } public static SKPointI operator +(SKPointI pt, SKPointI sz) { return new SKPointI(pt.X + sz.X, pt.Y + sz.Y); } public static SKPointI operator -(SKPointI pt, SKSizeI sz) { return new SKPointI(pt.X - sz.Width, pt.Y - sz.Height); } public static SKPointI operator -(SKPointI pt, SKPointI sz) { return new SKPointI(pt.X - sz.X, pt.Y - sz.Y); } public static explicit operator SKSizeI(SKPointI p) { return new SKSizeI(p.X, p.Y); } public static implicit operator SKPoint(SKPointI p) { return new SKPoint(p.X, p.Y); } public readonly bool Equals(SKPointI obj) { if (x == obj.x) { return y == obj.y; } return false; } public override readonly bool Equals(object obj) { if (obj is SKPointI obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKPointI left, SKPointI right) { return left.Equals(right); } public static bool operator !=(SKPointI left, SKPointI right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(x); hashCode.Add(y); return hashCode.ToHashCode(); } } public struct SKPoint3 : IEquatable { public static readonly SKPoint3 Empty; private float x; private float y; private float z; public readonly bool IsEmpty => this == Empty; public float X { readonly get { return x; } set { x = value; } } public float Y { readonly get { return y; } set { y = value; } } public float Z { readonly get { return z; } set { z = value; } } public SKPoint3(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } public override readonly string ToString() { return $"{{X={x}, Y={y}, Z={z}}}"; } public static SKPoint3 Add(SKPoint3 pt, SKPoint3 sz) { return pt + sz; } public static SKPoint3 Subtract(SKPoint3 pt, SKPoint3 sz) { return pt - sz; } public static SKPoint3 operator +(SKPoint3 pt, SKPoint3 sz) { return new SKPoint3(pt.X + sz.X, pt.Y + sz.Y, pt.Z + sz.Z); } public static SKPoint3 operator -(SKPoint3 pt, SKPoint3 sz) { return new SKPoint3(pt.X - sz.X, pt.Y - sz.Y, pt.Z - sz.Z); } public readonly bool Equals(SKPoint3 obj) { if (x == obj.x && y == obj.y) { return z == obj.z; } return false; } public override readonly bool Equals(object obj) { if (obj is SKPoint3 obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKPoint3 left, SKPoint3 right) { return left.Equals(right); } public static bool operator !=(SKPoint3 left, SKPoint3 right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(x); hashCode.Add(y); hashCode.Add(z); return hashCode.ToHashCode(); } } public struct SKSize : IEquatable { public static readonly SKSize Empty; private float w; private float h; public readonly bool IsEmpty => this == Empty; public float Width { readonly get { return w; } set { w = value; } } public float Height { readonly get { return h; } set { h = value; } } public SKSize(float width, float height) { w = width; h = height; } public SKSize(SKPoint pt) { w = pt.X; h = pt.Y; } public readonly SKPoint ToPoint() { return new SKPoint(w, h); } public readonly SKSizeI ToSizeI() { checked { int width = (int)w; int height = (int)h; return new SKSizeI(width, height); } } public override readonly string ToString() { return $"{{Width={w}, Height={h}}}"; } public static SKSize Add(SKSize sz1, SKSize sz2) { return sz1 + sz2; } public static SKSize Subtract(SKSize sz1, SKSize sz2) { return sz1 - sz2; } public static SKSize operator +(SKSize sz1, SKSize sz2) { return new SKSize(sz1.Width + sz2.Width, sz1.Height + sz2.Height); } public static SKSize operator -(SKSize sz1, SKSize sz2) { return new SKSize(sz1.Width - sz2.Width, sz1.Height - sz2.Height); } public static explicit operator SKPoint(SKSize size) { return new SKPoint(size.Width, size.Height); } public static implicit operator SKSize(SKSizeI size) { return new SKSize(size.Width, size.Height); } public readonly bool Equals(SKSize obj) { if (w == obj.w) { return h == obj.h; } return false; } public override readonly bool Equals(object obj) { if (obj is SKSize obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKSize left, SKSize right) { return left.Equals(right); } public static bool operator !=(SKSize left, SKSize right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(w); hashCode.Add(h); return hashCode.ToHashCode(); } } public struct SKSizeI : IEquatable { public static readonly SKSizeI Empty; private int w; private int h; public readonly bool IsEmpty => this == Empty; public int Width { readonly get { return w; } set { w = value; } } public int Height { readonly get { return h; } set { h = value; } } public SKSizeI(int width, int height) { w = width; h = height; } public SKSizeI(SKPointI pt) { w = pt.X; h = pt.Y; } public readonly SKPointI ToPointI() { return new SKPointI(w, h); } public override readonly string ToString() { return $"{{Width={w}, Height={h}}}"; } public static SKSizeI Add(SKSizeI sz1, SKSizeI sz2) { return sz1 + sz2; } public static SKSizeI Subtract(SKSizeI sz1, SKSizeI sz2) { return sz1 - sz2; } public static SKSizeI operator +(SKSizeI sz1, SKSizeI sz2) { return new SKSizeI(sz1.Width + sz2.Width, sz1.Height + sz2.Height); } public static SKSizeI operator -(SKSizeI sz1, SKSizeI sz2) { return new SKSizeI(sz1.Width - sz2.Width, sz1.Height - sz2.Height); } public static explicit operator SKPointI(SKSizeI size) { return new SKPointI(size.Width, size.Height); } public readonly bool Equals(SKSizeI obj) { if (w == obj.w) { return h == obj.h; } return false; } public override readonly bool Equals(object obj) { if (obj is SKSizeI obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKSizeI left, SKSizeI right) { return left.Equals(right); } public static bool operator !=(SKSizeI left, SKSizeI right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(w); hashCode.Add(h); return hashCode.ToHashCode(); } } public struct SKRect : IEquatable { public static readonly SKRect Empty; private float left; private float top; private float right; private float bottom; public readonly float MidX => left + Width / 2f; public readonly float MidY => top + Height / 2f; public readonly float Width => right - left; public readonly float Height => bottom - top; public readonly bool IsEmpty => this == Empty; public SKSize Size { readonly get { return new SKSize(Width, Height); } set { right = left + value.Width; bottom = top + value.Height; } } public SKPoint Location { readonly get { return new SKPoint(left, top); } set { this = Create(value, Size); } } public readonly SKRect Standardized { get { if (left > right) { if (top > bottom) { return new SKRect(right, bottom, left, top); } return new SKRect(right, top, left, bottom); } if (top > bottom) { return new SKRect(left, bottom, right, top); } return new SKRect(left, top, right, bottom); } } public float Left { readonly get { return left; } set { left = value; } } public float Top { readonly get { return top; } set { top = value; } } public float Right { readonly get { return right; } set { right = value; } } public float Bottom { readonly get { return bottom; } set { bottom = value; } } public SKRect(float left, float top, float right, float bottom) { this.left = left; this.right = right; this.top = top; this.bottom = bottom; } public readonly SKRect AspectFit(SKSize size) { return AspectResize(size, fit: true); } public readonly SKRect AspectFill(SKSize size) { return AspectResize(size, fit: false); } private readonly SKRect AspectResize(SKSize size, bool fit) { if (size.Width == 0f || size.Height == 0f || Width == 0f || Height == 0f) { return Create(MidX, MidY, 0f, 0f); } float width = size.Width; float height = size.Height; float num = width / height; float num2 = Width / Height; if (fit ? (num2 > num) : (num2 < num)) { height = Height; width = height * num; } else { width = Width; height = width / num; } float x = MidX - width / 2f; float y = MidY - height / 2f; return Create(x, y, width, height); } public static SKRect Inflate(SKRect rect, float x, float y) { SKRect result = new SKRect(rect.left, rect.top, rect.right, rect.bottom); result.Inflate(x, y); return result; } public void Inflate(SKSize size) { Inflate(size.Width, size.Height); } public void Inflate(float x, float y) { left -= x; top -= y; right += x; bottom += y; } public static SKRect Intersect(SKRect a, SKRect b) { if (!a.IntersectsWithInclusive(b)) { return Empty; } return new SKRect(Math.Max(a.left, b.left), Math.Max(a.top, b.top), Math.Min(a.right, b.right), Math.Min(a.bottom, b.bottom)); } public void Intersect(SKRect rect) { this = Intersect(this, rect); } public static SKRect Union(SKRect a, SKRect b) { return new SKRect(Math.Min(a.left, b.left), Math.Min(a.top, b.top), Math.Max(a.right, b.right), Math.Max(a.bottom, b.bottom)); } public void Union(SKRect rect) { this = Union(this, rect); } public static implicit operator SKRect(SKRectI r) { return new SKRect(r.Left, r.Top, r.Right, r.Bottom); } public readonly bool Contains(float x, float y) { if (x >= left && x < right && y >= top) { return y < bottom; } return false; } public readonly bool Contains(SKPoint pt) { return Contains(pt.X, pt.Y); } public readonly bool Contains(SKRect rect) { if (left <= rect.left && right >= rect.right && top <= rect.top) { return bottom >= rect.bottom; } return false; } public readonly bool IntersectsWith(SKRect rect) { if (left < rect.right && right > rect.left && top < rect.bottom) { return bottom > rect.top; } return false; } public readonly bool IntersectsWithInclusive(SKRect rect) { if (left <= rect.right && right >= rect.left && top <= rect.bottom) { return bottom >= rect.top; } return false; } public void Offset(float x, float y) { left += x; top += y; right += x; bottom += y; } public void Offset(SKPoint pos) { Offset(pos.X, pos.Y); } public override readonly string ToString() { return $"{{Left={Left},Top={Top},Width={Width},Height={Height}}}"; } public static SKRect Create(SKPoint location, SKSize size) { return Create(location.X, location.Y, size.Width, size.Height); } public static SKRect Create(SKSize size) { return Create(SKPoint.Empty, size); } public static SKRect Create(float width, float height) { return new SKRect(SKPoint.Empty.X, SKPoint.Empty.Y, width, height); } public static SKRect Create(float x, float y, float width, float height) { return new SKRect(x, y, x + width, y + height); } public readonly bool Equals(SKRect obj) { if (left == obj.left && top == obj.top && right == obj.right) { return bottom == obj.bottom; } return false; } public override readonly bool Equals(object obj) { if (obj is SKRect obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKRect left, SKRect right) { return left.Equals(right); } public static bool operator !=(SKRect left, SKRect right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(left); hashCode.Add(top); hashCode.Add(right); hashCode.Add(bottom); return hashCode.ToHashCode(); } } public struct SKRectI : IEquatable { public static readonly SKRectI Empty; private int left; private int top; private int right; private int bottom; public readonly int MidX => left + Width / 2; public readonly int MidY => top + Height / 2; public readonly int Width => right - left; public readonly int Height => bottom - top; public readonly bool IsEmpty => this == Empty; public SKSizeI Size { readonly get { return new SKSizeI(Width, Height); } set { right = left + value.Width; bottom = top + value.Height; } } public SKPointI Location { readonly get { return new SKPointI(left, top); } set { this = Create(value, Size); } } public readonly SKRectI Standardized { get { if (left > right) { if (top > bottom) { return new SKRectI(right, bottom, left, top); } return new SKRectI(right, top, left, bottom); } if (top > bottom) { return new SKRectI(left, bottom, right, top); } return new SKRectI(left, top, right, bottom); } } public int Left { readonly get { return left; } set { left = value; } } public int Top { readonly get { return top; } set { top = value; } } public int Right { readonly get { return right; } set { right = value; } } public int Bottom { readonly get { return bottom; } set { bottom = value; } } public SKRectI(int left, int top, int right, int bottom) { this.left = left; this.right = right; this.top = top; this.bottom = bottom; } public readonly SKRectI AspectFit(SKSizeI size) { return Floor(((SKRect)this).AspectFit(size)); } public readonly SKRectI AspectFill(SKSizeI size) { return Floor(((SKRect)this).AspectFill(size)); } public static SKRectI Ceiling(SKRect value) { return Ceiling(value, outwards: false); } public static SKRectI Ceiling(SKRect value, bool outwards) { checked { int num = (int)((outwards && value.Width > 0f) ? Math.Floor(value.Left) : Math.Ceiling(value.Left)); int num2 = (int)((outwards && value.Height > 0f) ? Math.Floor(value.Top) : Math.Ceiling(value.Top)); int num3 = (int)((outwards && value.Width < 0f) ? Math.Floor(value.Right) : Math.Ceiling(value.Right)); int num4 = (int)((outwards && value.Height < 0f) ? Math.Floor(value.Bottom) : Math.Ceiling(value.Bottom)); return new SKRectI(num, num2, num3, num4); } } public static SKRectI Inflate(SKRectI rect, int x, int y) { SKRectI result = new SKRectI(rect.left, rect.top, rect.right, rect.bottom); result.Inflate(x, y); return result; } public void Inflate(SKSizeI size) { Inflate(size.Width, size.Height); } public void Inflate(int width, int height) { left -= width; top -= height; right += width; bottom += height; } public static SKRectI Intersect(SKRectI a, SKRectI b) { if (!a.IntersectsWithInclusive(b)) { return Empty; } return new SKRectI(Math.Max(a.left, b.left), Math.Max(a.top, b.top), Math.Min(a.right, b.right), Math.Min(a.bottom, b.bottom)); } public void Intersect(SKRectI rect) { this = Intersect(this, rect); } public static SKRectI Round(SKRect value) { checked { int num = (int)Math.Round(value.Left); int num2 = (int)Math.Round(value.Top); int num3 = (int)Math.Round(value.Right); int num4 = (int)Math.Round(value.Bottom); return new SKRectI(num, num2, num3, num4); } } public static SKRectI Floor(SKRect value) { return Floor(value, inwards: false); } public static SKRectI Floor(SKRect value, bool inwards) { checked { int num = (int)((inwards && value.Width > 0f) ? Math.Ceiling(value.Left) : Math.Floor(value.Left)); int num2 = (int)((inwards && value.Height > 0f) ? Math.Ceiling(value.Top) : Math.Floor(value.Top)); int num3 = (int)((inwards && value.Width < 0f) ? Math.Ceiling(value.Right) : Math.Floor(value.Right)); int num4 = (int)((inwards && value.Height < 0f) ? Math.Ceiling(value.Bottom) : Math.Floor(value.Bottom)); return new SKRectI(num, num2, num3, num4); } } public static SKRectI Truncate(SKRect value) { checked { int num = (int)value.Left; int num2 = (int)value.Top; int num3 = (int)value.Right; int num4 = (int)value.Bottom; return new SKRectI(num, num2, num3, num4); } } public static SKRectI Union(SKRectI a, SKRectI b) { return new SKRectI(Math.Min(a.Left, b.Left), Math.Min(a.Top, b.Top), Math.Max(a.Right, b.Right), Math.Max(a.Bottom, b.Bottom)); } public void Union(SKRectI rect) { this = Union(this, rect); } public readonly bool Contains(int x, int y) { if (x >= left && x < right && y >= top) { return y < bottom; } return false; } public readonly bool Contains(SKPointI pt) { return Contains(pt.X, pt.Y); } public readonly bool Contains(SKRectI rect) { if (left <= rect.left && right >= rect.right && top <= rect.top) { return bottom >= rect.bottom; } return false; } public readonly bool IntersectsWith(SKRectI rect) { if (left < rect.right && right > rect.left && top < rect.bottom) { return bottom > rect.top; } return false; } public readonly bool IntersectsWithInclusive(SKRectI rect) { if (left <= rect.right && right >= rect.left && top <= rect.bottom) { return bottom >= rect.top; } return false; } public void Offset(int x, int y) { left += x; top += y; right += x; bottom += y; } public void Offset(SKPointI pos) { Offset(pos.X, pos.Y); } public override readonly string ToString() { return $"{{Left={Left},Top={Top},Width={Width},Height={Height}}}"; } public static SKRectI Create(SKSizeI size) { return Create(SKPointI.Empty.X, SKPointI.Empty.Y, size.Width, size.Height); } public static SKRectI Create(SKPointI location, SKSizeI size) { return Create(location.X, location.Y, size.Width, size.Height); } public static SKRectI Create(int width, int height) { return new SKRectI(SKPointI.Empty.X, SKPointI.Empty.X, width, height); } public static SKRectI Create(int x, int y, int width, int height) { return new SKRectI(x, y, x + width, y + height); } public readonly bool Equals(SKRectI obj) { if (left == obj.left && top == obj.top && right == obj.right) { return bottom == obj.bottom; } return false; } public override readonly bool Equals(object obj) { if (obj is SKRectI obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKRectI left, SKRectI right) { return left.Equals(right); } public static bool operator !=(SKRectI left, SKRectI right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(left); hashCode.Add(top); hashCode.Add(right); hashCode.Add(bottom); return hashCode.ToHashCode(); } } public class SK3dView : SKObject, ISKSkipObjectRegistration { public SKMatrix Matrix { get { SKMatrix matrix = SKMatrix.Identity; GetMatrix(ref matrix); return matrix; } } internal SK3dView(IntPtr x, bool owns) : base(x, owns) { } public SK3dView() : this(SkiaApi.sk_3dview_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SK3dView instance."); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_3dview_destroy(Handle); } public unsafe void GetMatrix(ref SKMatrix matrix) { fixed (SKMatrix* cmatrix = &matrix) { SkiaApi.sk_3dview_get_matrix(Handle, cmatrix); } } public void Save() { SkiaApi.sk_3dview_save(Handle); } public void Restore() { SkiaApi.sk_3dview_restore(Handle); } public void Translate(float x, float y, float z) { SkiaApi.sk_3dview_translate(Handle, x, y, z); } public void TranslateX(float x) { Translate(x, 0f, 0f); } public void TranslateY(float y) { Translate(0f, y, 0f); } public void TranslateZ(float z) { Translate(0f, 0f, z); } public void RotateXDegrees(float degrees) { SkiaApi.sk_3dview_rotate_x_degrees(Handle, degrees); } public void RotateYDegrees(float degrees) { SkiaApi.sk_3dview_rotate_y_degrees(Handle, degrees); } public void RotateZDegrees(float degrees) { SkiaApi.sk_3dview_rotate_z_degrees(Handle, degrees); } public void RotateXRadians(float radians) { SkiaApi.sk_3dview_rotate_x_radians(Handle, radians); } public void RotateYRadians(float radians) { SkiaApi.sk_3dview_rotate_y_radians(Handle, radians); } public void RotateZRadians(float radians) { SkiaApi.sk_3dview_rotate_z_radians(Handle, radians); } public float DotWithNormal(float dx, float dy, float dz) { return SkiaApi.sk_3dview_dot_with_normal(Handle, dx, dy, dz); } public void ApplyToCanvas(SKCanvas canvas) { if (canvas == null) { throw new ArgumentNullException("canvas"); } SkiaApi.sk_3dview_apply_to_canvas(Handle, canvas.Handle); } } public abstract class SKAbstractManagedStream : SKStreamAsset { private static readonly SKManagedStreamDelegates delegates; private int fromNative; unsafe static SKAbstractManagedStream() { delegates = new SKManagedStreamDelegates { fRead = ReadInternal, fPeek = PeekInternal, fIsAtEnd = IsAtEndInternal, fHasPosition = HasPositionInternal, fHasLength = HasLengthInternal, fRewind = RewindInternal, fGetPosition = GetPositionInternal, fSeek = SeekInternal, fMove = MoveInternal, fGetLength = GetLengthInternal, fDuplicate = DuplicateInternal, fFork = ForkInternal, fDestroy = DestroyInternal }; SkiaApi.sk_managedstream_set_procs(delegates); } protected SKAbstractManagedStream() : this(owns: true) { } protected unsafe SKAbstractManagedStream(bool owns) : base(IntPtr.Zero, owns) { IntPtr intPtr = DelegateProxies.CreateUserData(this, makeWeak: true); Handle = SkiaApi.sk_managedstream_new((void*)intPtr); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { if (Interlocked.CompareExchange(ref fromNative, 0, 0) == 0) { SkiaApi.sk_managedstream_destroy(Handle); } } protected abstract IntPtr OnRead(IntPtr buffer, IntPtr size); protected abstract IntPtr OnPeek(IntPtr buffer, IntPtr size); protected abstract bool OnIsAtEnd(); protected abstract bool OnHasPosition(); protected abstract bool OnHasLength(); protected abstract bool OnRewind(); protected abstract IntPtr OnGetPosition(); protected abstract IntPtr OnGetLength(); protected abstract bool OnSeek(IntPtr position); protected abstract bool OnMove(int offset); protected abstract IntPtr OnCreateNew(); protected virtual IntPtr OnFork() { IntPtr intPtr = OnCreateNew(); SkiaApi.sk_stream_seek(intPtr, SkiaApi.sk_stream_get_position(Handle)); return intPtr; } protected virtual IntPtr OnDuplicate() { return OnCreateNew(); } [MonoPInvokeCallback(typeof(SKManagedStreamReadProxyDelegate))] private unsafe static IntPtr ReadInternal(IntPtr s, void* context, void* buffer, IntPtr size) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnRead((IntPtr)buffer, size); } [MonoPInvokeCallback(typeof(SKManagedStreamPeekProxyDelegate))] private unsafe static IntPtr PeekInternal(IntPtr s, void* context, void* buffer, IntPtr size) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnPeek((IntPtr)buffer, size); } [MonoPInvokeCallback(typeof(SKManagedStreamIsAtEndProxyDelegate))] private unsafe static bool IsAtEndInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnIsAtEnd(); } [MonoPInvokeCallback(typeof(SKManagedStreamHasPositionProxyDelegate))] private unsafe static bool HasPositionInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnHasPosition(); } [MonoPInvokeCallback(typeof(SKManagedStreamHasLengthProxyDelegate))] private unsafe static bool HasLengthInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnHasLength(); } [MonoPInvokeCallback(typeof(SKManagedStreamRewindProxyDelegate))] private unsafe static bool RewindInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnRewind(); } [MonoPInvokeCallback(typeof(SKManagedStreamGetPositionProxyDelegate))] private unsafe static IntPtr GetPositionInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnGetPosition(); } [MonoPInvokeCallback(typeof(SKManagedStreamSeekProxyDelegate))] private unsafe static bool SeekInternal(IntPtr s, void* context, IntPtr position) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnSeek(position); } [MonoPInvokeCallback(typeof(SKManagedStreamMoveProxyDelegate))] private unsafe static bool MoveInternal(IntPtr s, void* context, int offset) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnMove(offset); } [MonoPInvokeCallback(typeof(SKManagedStreamGetLengthProxyDelegate))] private unsafe static IntPtr GetLengthInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnGetLength(); } [MonoPInvokeCallback(typeof(SKManagedStreamDuplicateProxyDelegate))] private unsafe static IntPtr DuplicateInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnDuplicate(); } [MonoPInvokeCallback(typeof(SKManagedStreamForkProxyDelegate))] private unsafe static IntPtr ForkInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnFork(); } [MonoPInvokeCallback(typeof(SKManagedStreamDestroyProxyDelegate))] private unsafe static void DestroyInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); if (userData != null) { Interlocked.Exchange(ref userData.fromNative, 1); userData.Dispose(); } gch.Free(); } } public abstract class SKAbstractManagedWStream : SKWStream { private static readonly SKManagedWStreamDelegates delegates; private int fromNative; unsafe static SKAbstractManagedWStream() { delegates = new SKManagedWStreamDelegates { fWrite = WriteInternal, fFlush = FlushInternal, fBytesWritten = BytesWrittenInternal, fDestroy = DestroyInternal }; SkiaApi.sk_managedwstream_set_procs(delegates); } protected SKAbstractManagedWStream() : this(owns: true) { } protected unsafe SKAbstractManagedWStream(bool owns) : base(IntPtr.Zero, owns) { IntPtr intPtr = DelegateProxies.CreateUserData(this, makeWeak: true); Handle = SkiaApi.sk_managedwstream_new((void*)intPtr); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { if (Interlocked.CompareExchange(ref fromNative, 0, 0) == 0) { SkiaApi.sk_managedwstream_destroy(Handle); } } protected abstract bool OnWrite(IntPtr buffer, IntPtr size); protected abstract void OnFlush(); protected abstract IntPtr OnBytesWritten(); [MonoPInvokeCallback(typeof(SKManagedWStreamWriteProxyDelegate))] private unsafe static bool WriteInternal(IntPtr s, void* context, void* buffer, IntPtr size) { GCHandle gch; SKAbstractManagedWStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnWrite((IntPtr)buffer, size); } [MonoPInvokeCallback(typeof(SKManagedWStreamFlushProxyDelegate))] private unsafe static void FlushInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedWStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); userData.OnFlush(); } [MonoPInvokeCallback(typeof(SKManagedWStreamBytesWrittenProxyDelegate))] private unsafe static IntPtr BytesWrittenInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedWStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnBytesWritten(); } [MonoPInvokeCallback(typeof(SKManagedWStreamDestroyProxyDelegate))] private unsafe static void DestroyInternal(IntPtr s, void* context) { GCHandle gch; SKAbstractManagedWStream userData = DelegateProxies.GetUserData((IntPtr)context, out gch); if (userData != null) { Interlocked.Exchange(ref userData.fromNative, 1); userData.Dispose(); } gch.Free(); } } public class SKAutoCoInitialize : IDisposable { private long hResult; private const long S_OK = 0L; private const long RPC_E_CHANGED_MODE = 2147549446L; private const uint COINIT_MULTITHREADED = 0u; private const uint COINIT_APARTMENTTHREADED = 2u; private const uint COINIT_DISABLE_OLE1DDE = 4u; private const uint COINIT_SPEED_OVER_MEMORY = 8u; public bool Initialized { get { if (hResult < 0) { return hResult == 2147549446u; } return true; } } public SKAutoCoInitialize() { if (PlatformConfiguration.IsWindows) { hResult = CoInitializeEx(IntPtr.Zero, 6u); } else { hResult = 0L; } } public void Uninitialize() { if (hResult >= 0) { if (PlatformConfiguration.IsWindows) { CoUninitialize(); } hResult = -1L; } } public void Dispose() { Uninitialize(); } [DllImport("ole32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, SetLastError = true)] private static extern long CoInitializeEx([Optional][In] IntPtr pvReserved, [In] uint dwCoInit); [DllImport("ole32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, SetLastError = true)] private static extern void CoUninitialize(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public enum SKBitmapResizeMethod { Box, Triangle, Lanczos3, Hamming, Mitchell } public class SKBitmap : SKObject, ISKSkipObjectRegistration { private const string UnsupportedColorTypeMessage = "Setting the ColorTable is only supported for bitmaps with ColorTypes of Index8."; private const string UnableToAllocatePixelsMessage = "Unable to allocate pixels for the bitmap."; public bool ReadyToDraw => SkiaApi.sk_bitmap_ready_to_draw(Handle); public unsafe SKImageInfo Info { get { SKImageInfoNative native = default(SKImageInfoNative); SkiaApi.sk_bitmap_get_info(Handle, &native); return SKImageInfoNative.ToManaged(ref native); } } public int Width => Info.Width; public int Height => Info.Height; public SKColorType ColorType => Info.ColorType; public SKAlphaType AlphaType => Info.AlphaType; public SKColorSpace ColorSpace => Info.ColorSpace; public int BytesPerPixel => Info.BytesPerPixel; public int RowBytes => (int)SkiaApi.sk_bitmap_get_row_bytes(Handle); public int ByteCount => (int)SkiaApi.sk_bitmap_get_byte_count(Handle); public byte[] Bytes { get { byte[] result = GetPixelSpan().ToArray(); GC.KeepAlive(this); return result; } } public unsafe SKColor[] Pixels { get { SKImageInfo info = Info; SKColor[] array = new SKColor[info.Width * info.Height]; fixed (SKColor* colors = array) { SkiaApi.sk_bitmap_get_pixel_colors(Handle, (uint*)colors); } return array; } set { if (value == null) { throw new ArgumentNullException("value"); } SKImageInfo info = Info; if (info.Width * info.Height != value.Length) { throw new ArgumentException($"The number of pixels must equal Width x Height, or {info.Width * info.Height}.", "value"); } fixed (SKColor* ptr = value) { SKImageInfo info2 = new SKImageInfo(info.Width, info.Height, SKColorType.Bgra8888, SKAlphaType.Unpremul); using SKBitmap sKBitmap = new SKBitmap(); sKBitmap.InstallPixels(info2, (IntPtr)ptr); using SKShader shader = sKBitmap.ToShader(); using SKCanvas sKCanvas = new SKCanvas(this); using SKPaint paint = new SKPaint { Shader = shader, BlendMode = SKBlendMode.Src }; sKCanvas.DrawPaint(paint); } } } public bool IsEmpty => Info.IsEmpty; public bool IsNull => SkiaApi.sk_bitmap_is_null(Handle); public bool DrawsNothing { get { if (!IsEmpty) { return IsNull; } return true; } } public bool IsImmutable => SkiaApi.sk_bitmap_is_immutable(Handle); [Obsolete] public bool IsVolatile { get { return false; } set { } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported.")] public SKColorTable ColorTable => null; internal SKBitmap(IntPtr handle, bool owns) : base(handle, owns) { } public SKBitmap() : this(SkiaApi.sk_bitmap_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKBitmap instance."); } } public SKBitmap(int width, int height, bool isOpaque = false) : this(width, height, SKImageInfo.PlatformColorType, isOpaque ? SKAlphaType.Opaque : SKAlphaType.Premul) { } public SKBitmap(int width, int height, SKColorType colorType, SKAlphaType alphaType) : this(new SKImageInfo(width, height, colorType, alphaType)) { } public SKBitmap(int width, int height, SKColorType colorType, SKAlphaType alphaType, SKColorSpace colorspace) : this(new SKImageInfo(width, height, colorType, alphaType, colorspace)) { } public SKBitmap(SKImageInfo info) : this(info, info.RowBytes) { } public SKBitmap(SKImageInfo info, int rowBytes) : this() { if (!TryAllocPixels(info, rowBytes)) { throw new Exception("Unable to allocate pixels for the bitmap."); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use SKBitmap(SKImageInfo, SKBitmapAllocFlags) instead.")] public SKBitmap(SKImageInfo info, SKColorTable ctable, SKBitmapAllocFlags flags) : this(info, SKBitmapAllocFlags.None) { } public SKBitmap(SKImageInfo info, SKBitmapAllocFlags flags) : this() { if (!TryAllocPixels(info, flags)) { throw new Exception("Unable to allocate pixels for the bitmap."); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use SKBitmap(SKImageInfo) instead.")] public SKBitmap(SKImageInfo info, SKColorTable ctable) : this(info, SKBitmapAllocFlags.None) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_bitmap_destructor(Handle); } public bool TryAllocPixels(SKImageInfo info) { return TryAllocPixels(info, info.RowBytes); } public unsafe bool TryAllocPixels(SKImageInfo info, int rowBytes) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return SkiaApi.sk_bitmap_try_alloc_pixels(Handle, &sKImageInfoNative, (IntPtr)rowBytes); } public unsafe bool TryAllocPixels(SKImageInfo info, SKBitmapAllocFlags flags) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return SkiaApi.sk_bitmap_try_alloc_pixels_with_flags(Handle, &sKImageInfoNative, (uint)flags); } public void Reset() { SkiaApi.sk_bitmap_reset(Handle); } public void SetImmutable() { SkiaApi.sk_bitmap_set_immutable(Handle); } public void Erase(SKColor color) { SkiaApi.sk_bitmap_erase(Handle, (uint)color); } public unsafe void Erase(SKColor color, SKRectI rect) { SkiaApi.sk_bitmap_erase_rect(Handle, (uint)color, &rect); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public unsafe byte GetAddr8(int x, int y) { return *SkiaApi.sk_bitmap_get_addr_8(Handle, x, y); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public unsafe ushort GetAddr16(int x, int y) { return *SkiaApi.sk_bitmap_get_addr_16(Handle, x, y); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public unsafe uint GetAddr32(int x, int y) { return *SkiaApi.sk_bitmap_get_addr_32(Handle, x, y); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetAddress instead.")] public IntPtr GetAddr(int x, int y) { return GetAddress(x, y); } public unsafe IntPtr GetAddress(int x, int y) { return (IntPtr)SkiaApi.sk_bitmap_get_addr(Handle, x, y); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use GetPixel(int, int) instead.")] public SKPMColor GetIndex8Color(int x, int y) { return (SKPMColor)GetPixel(x, y); } public SKColor GetPixel(int x, int y) { return SkiaApi.sk_bitmap_get_pixel_color(Handle, x, y); } public void SetPixel(int x, int y, SKColor color) { SKImageInfo info = Info; if (x < 0 || x >= info.Width) { throw new ArgumentOutOfRangeException("x"); } if (y < 0 || y >= info.Height) { throw new ArgumentOutOfRangeException("y"); } using SKCanvas sKCanvas = new SKCanvas(this); sKCanvas.DrawPoint(x, y, color); } public bool CanCopyTo(SKColorType colorType) { if (colorType == SKColorType.Unknown) { return false; } using SKBitmap sKBitmap = new SKBitmap(); SKImageInfo info = Info.WithColorType(colorType).WithSize(1, 1); return sKBitmap.TryAllocPixels(info); } public SKBitmap Copy() { return Copy(ColorType); } public SKBitmap Copy(SKColorType colorType) { SKBitmap sKBitmap = new SKBitmap(); if (!CopyTo(sKBitmap, colorType)) { sKBitmap.Dispose(); sKBitmap = null; } return sKBitmap; } public bool CopyTo(SKBitmap destination) { if (destination == null) { throw new ArgumentNullException("destination"); } return CopyTo(destination, ColorType); } public bool CopyTo(SKBitmap destination, SKColorType colorType) { if (destination == null) { throw new ArgumentNullException("destination"); } if (colorType == SKColorType.Unknown) { return false; } using SKPixmap sKPixmap = PeekPixels(); if (sKPixmap == null) { return false; } using SKBitmap sKBitmap = new SKBitmap(); SKImageInfo info = sKPixmap.Info.WithColorType(colorType); if (!sKBitmap.TryAllocPixels(info)) { return false; } using SKCanvas sKCanvas = new SKCanvas(sKBitmap); using SKPaint paint = new SKPaint { Shader = ToShader(), BlendMode = SKBlendMode.Src }; sKCanvas.DrawPaint(paint); destination.Swap(sKBitmap); return true; } public unsafe bool ExtractSubset(SKBitmap destination, SKRectI subset) { if (destination == null) { throw new ArgumentNullException("destination"); } return SkiaApi.sk_bitmap_extract_subset(Handle, destination.Handle, &subset); } public bool ExtractAlpha(SKBitmap destination) { SKPointI offset; return ExtractAlpha(destination, null, out offset); } public bool ExtractAlpha(SKBitmap destination, out SKPointI offset) { return ExtractAlpha(destination, null, out offset); } public bool ExtractAlpha(SKBitmap destination, SKPaint paint) { SKPointI offset; return ExtractAlpha(destination, paint, out offset); } public unsafe bool ExtractAlpha(SKBitmap destination, SKPaint paint, out SKPointI offset) { if (destination == null) { throw new ArgumentNullException("destination"); } fixed (SKPointI* offset2 = &offset) { return SkiaApi.sk_bitmap_extract_alpha(Handle, destination.Handle, paint?.Handle ?? IntPtr.Zero, offset2); } } public IntPtr GetPixels() { IntPtr length; return GetPixels(out length); } public unsafe ReadOnlySpan GetPixelSpan() { IntPtr length; return new ReadOnlySpan((void*)GetPixels(out length), (int)length); } public unsafe IntPtr GetPixels(out IntPtr length) { fixed (IntPtr* length2 = &length) { return (IntPtr)SkiaApi.sk_bitmap_get_pixels(Handle, length2); } } public unsafe void SetPixels(IntPtr pixels) { SkiaApi.sk_bitmap_set_pixels(Handle, (void*)pixels); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use SetPixels(IntPtr) instead.")] public void SetPixels(IntPtr pixels, SKColorTable ct) { SetPixels(pixels); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported.")] public void SetColorTable(SKColorTable ct) { } public static SKImageInfo DecodeBounds(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKCodec sKCodec = SKCodec.Create(stream); return sKCodec?.Info ?? SKImageInfo.Empty; } public static SKImageInfo DecodeBounds(SKStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKCodec sKCodec = SKCodec.Create(stream); return sKCodec?.Info ?? SKImageInfo.Empty; } public static SKImageInfo DecodeBounds(SKData data) { if (data == null) { throw new ArgumentNullException("data"); } using SKCodec sKCodec = SKCodec.Create(data); return sKCodec?.Info ?? SKImageInfo.Empty; } public static SKImageInfo DecodeBounds(string filename) { if (filename == null) { throw new ArgumentNullException("filename"); } using SKCodec sKCodec = SKCodec.Create(filename); return sKCodec?.Info ?? SKImageInfo.Empty; } public static SKImageInfo DecodeBounds(byte[] buffer) { return DecodeBounds(buffer.AsSpan()); } public unsafe static SKImageInfo DecodeBounds(ReadOnlySpan buffer) { fixed (byte* ptr = buffer) { using SKData data = SKData.Create((IntPtr)ptr, buffer.Length); using SKCodec sKCodec = SKCodec.Create(data); return sKCodec?.Info ?? SKImageInfo.Empty; } } public static SKBitmap Decode(SKCodec codec) { if (codec == null) { throw new ArgumentNullException("codec"); } SKImageInfo info = codec.Info; if (info.AlphaType == SKAlphaType.Unpremul) { info.AlphaType = SKAlphaType.Premul; } info.ColorSpace = null; return Decode(codec, info); } public static SKBitmap Decode(SKCodec codec, SKImageInfo bitmapInfo) { if (codec == null) { throw new ArgumentNullException("codec"); } SKBitmap sKBitmap = new SKBitmap(bitmapInfo); IntPtr length; SKCodecResult pixels = codec.GetPixels(bitmapInfo, sKBitmap.GetPixels(out length)); if (pixels != SKCodecResult.Success && pixels != SKCodecResult.IncompleteInput) { sKBitmap.Dispose(); sKBitmap = null; } return sKBitmap; } public static SKBitmap Decode(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKCodec sKCodec = SKCodec.Create(stream); if (sKCodec == null) { return null; } return Decode(sKCodec); } public static SKBitmap Decode(Stream stream, SKImageInfo bitmapInfo) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKCodec sKCodec = SKCodec.Create(stream); if (sKCodec == null) { return null; } return Decode(sKCodec, bitmapInfo); } public static SKBitmap Decode(SKStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKCodec sKCodec = SKCodec.Create(stream); if (sKCodec == null) { return null; } return Decode(sKCodec); } public static SKBitmap Decode(SKStream stream, SKImageInfo bitmapInfo) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKCodec sKCodec = SKCodec.Create(stream); if (sKCodec == null) { return null; } return Decode(sKCodec, bitmapInfo); } public static SKBitmap Decode(SKData data) { if (data == null) { throw new ArgumentNullException("data"); } using SKCodec sKCodec = SKCodec.Create(data); if (sKCodec == null) { return null; } return Decode(sKCodec); } public static SKBitmap Decode(SKData data, SKImageInfo bitmapInfo) { if (data == null) { throw new ArgumentNullException("data"); } using SKCodec sKCodec = SKCodec.Create(data); if (sKCodec == null) { return null; } return Decode(sKCodec, bitmapInfo); } public static SKBitmap Decode(string filename) { if (filename == null) { throw new ArgumentNullException("filename"); } using SKCodec sKCodec = SKCodec.Create(filename); if (sKCodec == null) { return null; } return Decode(sKCodec); } public static SKBitmap Decode(string filename, SKImageInfo bitmapInfo) { if (filename == null) { throw new ArgumentNullException("filename"); } using SKCodec sKCodec = SKCodec.Create(filename); if (sKCodec == null) { return null; } return Decode(sKCodec, bitmapInfo); } public static SKBitmap Decode(byte[] buffer) { return Decode(buffer.AsSpan()); } public static SKBitmap Decode(byte[] buffer, SKImageInfo bitmapInfo) { return Decode(buffer.AsSpan(), bitmapInfo); } public unsafe static SKBitmap Decode(ReadOnlySpan buffer) { fixed (byte* ptr = buffer) { using SKData data = SKData.Create((IntPtr)ptr, buffer.Length); using SKCodec codec = SKCodec.Create(data); return Decode(codec); } } public unsafe static SKBitmap Decode(ReadOnlySpan buffer, SKImageInfo bitmapInfo) { fixed (byte* ptr = buffer) { using SKData data = SKData.Create((IntPtr)ptr, buffer.Length); using SKCodec codec = SKCodec.Create(data); return Decode(codec, bitmapInfo); } } public bool InstallPixels(SKImageInfo info, IntPtr pixels) { return InstallPixels(info, pixels, info.RowBytes, null, null); } public bool InstallPixels(SKImageInfo info, IntPtr pixels, int rowBytes) { return InstallPixels(info, pixels, rowBytes, null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use InstallPixels(SKImageInfo, IntPtr, int) instead.")] public bool InstallPixels(SKImageInfo info, IntPtr pixels, int rowBytes, SKColorTable ctable) { return InstallPixels(info, pixels, rowBytes, null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use InstallPixels(SKImageInfo, IntPtr, int, SKBitmapReleaseDelegate, object) instead.")] public bool InstallPixels(SKImageInfo info, IntPtr pixels, int rowBytes, SKColorTable ctable, SKBitmapReleaseDelegate releaseProc, object context) { return InstallPixels(info, pixels, rowBytes, releaseProc, context); } public bool InstallPixels(SKImageInfo info, IntPtr pixels, int rowBytes, SKBitmapReleaseDelegate releaseProc) { return InstallPixels(info, pixels, rowBytes, releaseProc, null); } public unsafe bool InstallPixels(SKImageInfo info, IntPtr pixels, int rowBytes, SKBitmapReleaseDelegate releaseProc, object context) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); SKBitmapReleaseDelegate managedDel = ((releaseProc != null && context != null) ? ((SKBitmapReleaseDelegate)delegate(IntPtr addr, object _) { releaseProc(addr, context); }) : releaseProc); GCHandle gch; IntPtr contextPtr; SKBitmapReleaseProxyDelegate releaseProc2 = DelegateProxies.Create(managedDel, DelegateProxies.SKBitmapReleaseDelegateProxy, out gch, out contextPtr); return SkiaApi.sk_bitmap_install_pixels(Handle, &sKImageInfoNative, (void*)pixels, (IntPtr)rowBytes, releaseProc2, (void*)contextPtr); } public bool InstallPixels(SKPixmap pixmap) { return SkiaApi.sk_bitmap_install_pixels_with_pixmap(Handle, pixmap.Handle); } public unsafe bool InstallMaskPixels(SKMask mask) { return SkiaApi.sk_bitmap_install_mask_pixels(Handle, &mask); } public void NotifyPixelsChanged() { SkiaApi.sk_bitmap_notify_pixels_changed(Handle); } public SKPixmap PeekPixels() { SKPixmap sKPixmap = new SKPixmap(); if (PeekPixels(sKPixmap)) { return sKPixmap; } sKPixmap.Dispose(); return null; } public bool PeekPixels(SKPixmap pixmap) { if (pixmap == null) { throw new ArgumentNullException("pixmap"); } bool flag = SkiaApi.sk_bitmap_peek_pixels(Handle, pixmap.Handle); if (flag) { pixmap.pixelSource = this; } return flag; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Resize(SKImageInfo, SKFilterQuality) instead.")] public SKBitmap Resize(SKImageInfo info, SKBitmapResizeMethod method) { return Resize(info, method.ToFilterQuality()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ScalePixels(SKBitmap, SKFilterQuality) instead.")] public bool Resize(SKBitmap dst, SKBitmapResizeMethod method) { return ScalePixels(dst, method.ToFilterQuality()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ScalePixels(SKBitmap, SKFilterQuality) instead.")] public static bool Resize(SKBitmap dst, SKBitmap src, SKBitmapResizeMethod method) { return src.ScalePixels(dst, method.ToFilterQuality()); } public SKBitmap Resize(SKImageInfo info, SKFilterQuality quality) { if (info.IsEmpty) { return null; } SKBitmap sKBitmap = new SKBitmap(info); if (ScalePixels(sKBitmap, quality)) { return sKBitmap; } sKBitmap.Dispose(); return null; } public SKBitmap Resize(SKSizeI size, SKFilterQuality quality) { return Resize(Info.WithSize(size), quality); } public bool ScalePixels(SKBitmap destination, SKFilterQuality quality) { if (destination == null) { throw new ArgumentNullException("destination"); } using SKPixmap destination2 = destination.PeekPixels(); return ScalePixels(destination2, quality); } public bool ScalePixels(SKPixmap destination, SKFilterQuality quality) { if (destination == null) { throw new ArgumentNullException("destination"); } using SKPixmap sKPixmap = PeekPixels(); return sKPixmap.ScalePixels(destination, quality); } public static SKBitmap FromImage(SKImage image) { if (image == null) { throw new ArgumentNullException("image"); } SKImageInfo sKImageInfo = new SKImageInfo(image.Width, image.Height, SKImageInfo.PlatformColorType, image.AlphaType); SKBitmap sKBitmap = new SKBitmap(sKImageInfo); if (!image.ReadPixels(sKImageInfo, sKBitmap.GetPixels(), sKImageInfo.RowBytes, 0, 0)) { sKBitmap.Dispose(); sKBitmap = null; } return sKBitmap; } public SKData Encode(SKEncodedImageFormat format, int quality) { using SKPixmap sKPixmap = PeekPixels(); return sKPixmap?.Encode(format, quality); } public bool Encode(Stream dst, SKEncodedImageFormat format, int quality) { using SKManagedWStream dst2 = new SKManagedWStream(dst); return Encode(dst2, format, quality); } public bool Encode(SKWStream dst, SKEncodedImageFormat format, int quality) { if (dst == null) { throw new ArgumentNullException("dst"); } using SKPixmap sKPixmap = PeekPixels(); return sKPixmap?.Encode(dst, format, quality) ?? false; } private void Swap(SKBitmap other) { SkiaApi.sk_bitmap_swap(Handle, other.Handle); } public SKShader ToShader() { return ToShader(SKShaderTileMode.Clamp, SKShaderTileMode.Clamp); } public unsafe SKShader ToShader(SKShaderTileMode tmx, SKShaderTileMode tmy) { return SKShader.GetObject(SkiaApi.sk_bitmap_make_shader(Handle, tmx, tmy, null)); } public unsafe SKShader ToShader(SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix) { return SKShader.GetObject(SkiaApi.sk_bitmap_make_shader(Handle, tmx, tmy, &localMatrix)); } } public class SKCanvas : SKObject { private const int PatchCornerCount = 4; private const int PatchCubicsCount = 12; private const double RadiansCircle = Math.PI * 2.0; private const double DegreesCircle = 360.0; public SKRect LocalClipBounds { get { GetLocalClipBounds(out var bounds); return bounds; } } public SKRectI DeviceClipBounds { get { GetDeviceClipBounds(out var bounds); return bounds; } } public bool IsClipEmpty => SkiaApi.sk_canvas_is_clip_empty(Handle); public bool IsClipRect => SkiaApi.sk_canvas_is_clip_rect(Handle); public unsafe SKMatrix TotalMatrix { get { SKMatrix result = default(SKMatrix); SkiaApi.sk_canvas_get_total_matrix(Handle, &result); return result; } } public int SaveCount => SkiaApi.sk_canvas_get_save_count(Handle); internal SKCanvas(IntPtr handle, bool owns) : base(handle, owns) { } public SKCanvas(SKBitmap bitmap) : this(IntPtr.Zero, owns: true) { if (bitmap == null) { throw new ArgumentNullException("bitmap"); } Handle = SkiaApi.sk_canvas_new_from_bitmap(bitmap.Handle); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_canvas_destroy(Handle); } public void Discard() { SkiaApi.sk_canvas_discard(Handle); } public unsafe bool QuickReject(SKRect rect) { return SkiaApi.sk_canvas_quick_reject(Handle, &rect); } public bool QuickReject(SKPath path) { if (path == null) { throw new ArgumentNullException("path"); } if (!path.IsEmpty) { return QuickReject(path.Bounds); } return true; } public int Save() { if (Handle == IntPtr.Zero) { throw new ObjectDisposedException("SKCanvas"); } return SkiaApi.sk_canvas_save(Handle); } public unsafe int SaveLayer(SKRect limit, SKPaint paint) { return SkiaApi.sk_canvas_save_layer(Handle, &limit, paint?.Handle ?? IntPtr.Zero); } public unsafe int SaveLayer(SKPaint paint) { return SkiaApi.sk_canvas_save_layer(Handle, null, paint?.Handle ?? IntPtr.Zero); } public int SaveLayer() { return SaveLayer(null); } public void DrawColor(SKColor color, SKBlendMode mode = SKBlendMode.Src) { SkiaApi.sk_canvas_draw_color(Handle, (uint)color, mode); } public void DrawColor(SKColorF color, SKBlendMode mode = SKBlendMode.Src) { SkiaApi.sk_canvas_draw_color4f(Handle, color, mode); } public void DrawLine(SKPoint p0, SKPoint p1, SKPaint paint) { DrawLine(p0.X, p0.Y, p1.X, p1.Y, paint); } public void DrawLine(float x0, float y0, float x1, float y1, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_line(Handle, x0, y0, x1, y1, paint.Handle); } public void Clear() { Clear(SKColors.Empty); } public void Clear(SKColor color) { SkiaApi.sk_canvas_clear(Handle, (uint)color); } public void Clear(SKColorF color) { SkiaApi.sk_canvas_clear_color4f(Handle, color); } public void Restore() { SkiaApi.sk_canvas_restore(Handle); } public void RestoreToCount(int count) { SkiaApi.sk_canvas_restore_to_count(Handle, count); } public void Translate(float dx, float dy) { if (dx != 0f || dy != 0f) { SkiaApi.sk_canvas_translate(Handle, dx, dy); } } public void Translate(SKPoint point) { if (!point.IsEmpty) { SkiaApi.sk_canvas_translate(Handle, point.X, point.Y); } } public void Scale(float s) { if (s != 1f) { SkiaApi.sk_canvas_scale(Handle, s, s); } } public void Scale(float sx, float sy) { if (sx != 1f || sy != 1f) { SkiaApi.sk_canvas_scale(Handle, sx, sy); } } public void Scale(SKPoint size) { if (!size.IsEmpty) { SkiaApi.sk_canvas_scale(Handle, size.X, size.Y); } } public void Scale(float sx, float sy, float px, float py) { if (sx != 1f || sy != 1f) { Translate(px, py); Scale(sx, sy); Translate(0f - px, 0f - py); } } public void RotateDegrees(float degrees) { if ((double)degrees % 360.0 != 0.0) { SkiaApi.sk_canvas_rotate_degrees(Handle, degrees); } } public void RotateRadians(float radians) { if ((double)radians % (Math.PI * 2.0) != 0.0) { SkiaApi.sk_canvas_rotate_radians(Handle, radians); } } public void RotateDegrees(float degrees, float px, float py) { if ((double)degrees % 360.0 != 0.0) { Translate(px, py); RotateDegrees(degrees); Translate(0f - px, 0f - py); } } public void RotateRadians(float radians, float px, float py) { if ((double)radians % (Math.PI * 2.0) != 0.0) { Translate(px, py); RotateRadians(radians); Translate(0f - px, 0f - py); } } public void Skew(float sx, float sy) { if (sx != 0f || sy != 0f) { SkiaApi.sk_canvas_skew(Handle, sx, sy); } } public void Skew(SKPoint skew) { if (!skew.IsEmpty) { SkiaApi.sk_canvas_skew(Handle, skew.X, skew.Y); } } public unsafe void Concat(ref SKMatrix m) { fixed (SKMatrix* param = &m) { SkiaApi.sk_canvas_concat(Handle, param); } } public unsafe void ClipRect(SKRect rect, SKClipOperation operation = SKClipOperation.Intersect, bool antialias = false) { SkiaApi.sk_canvas_clip_rect_with_operation(Handle, &rect, operation, antialias); } public void ClipRoundRect(SKRoundRect rect, SKClipOperation operation = SKClipOperation.Intersect, bool antialias = false) { if (rect == null) { throw new ArgumentNullException("rect"); } SkiaApi.sk_canvas_clip_rrect_with_operation(Handle, rect.Handle, operation, antialias); } public void ClipPath(SKPath path, SKClipOperation operation = SKClipOperation.Intersect, bool antialias = false) { if (path == null) { throw new ArgumentNullException("path"); } SkiaApi.sk_canvas_clip_path_with_operation(Handle, path.Handle, operation, antialias); } public void ClipRegion(SKRegion region, SKClipOperation operation = SKClipOperation.Intersect) { if (region == null) { throw new ArgumentNullException("region"); } SkiaApi.sk_canvas_clip_region(Handle, region.Handle, operation); } public unsafe bool GetLocalClipBounds(out SKRect bounds) { fixed (SKRect* cbounds = &bounds) { return SkiaApi.sk_canvas_get_local_clip_bounds(Handle, cbounds); } } public unsafe bool GetDeviceClipBounds(out SKRectI bounds) { fixed (SKRectI* cbounds = &bounds) { return SkiaApi.sk_canvas_get_device_clip_bounds(Handle, cbounds); } } public void DrawPaint(SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_paint(Handle, paint.Handle); } public void DrawRegion(SKRegion region, SKPaint paint) { if (region == null) { throw new ArgumentNullException("region"); } if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_region(Handle, region.Handle, paint.Handle); } public void DrawRect(float x, float y, float w, float h, SKPaint paint) { DrawRect(SKRect.Create(x, y, w, h), paint); } public unsafe void DrawRect(SKRect rect, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_rect(Handle, &rect, paint.Handle); } public void DrawRoundRect(SKRoundRect rect, SKPaint paint) { if (rect == null) { throw new ArgumentNullException("rect"); } if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_rrect(Handle, rect.Handle, paint.Handle); } public void DrawRoundRect(float x, float y, float w, float h, float rx, float ry, SKPaint paint) { DrawRoundRect(SKRect.Create(x, y, w, h), rx, ry, paint); } public unsafe void DrawRoundRect(SKRect rect, float rx, float ry, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_round_rect(Handle, &rect, rx, ry, paint.Handle); } public void DrawRoundRect(SKRect rect, SKSize r, SKPaint paint) { DrawRoundRect(rect, r.Width, r.Height, paint); } public void DrawOval(float cx, float cy, float rx, float ry, SKPaint paint) { DrawOval(new SKRect(cx - rx, cy - ry, cx + rx, cy + ry), paint); } public void DrawOval(SKPoint c, SKSize r, SKPaint paint) { DrawOval(c.X, c.Y, r.Width, r.Height, paint); } public unsafe void DrawOval(SKRect rect, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_oval(Handle, &rect, paint.Handle); } public void DrawCircle(float cx, float cy, float radius, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_circle(Handle, cx, cy, radius, paint.Handle); } public void DrawCircle(SKPoint c, float radius, SKPaint paint) { DrawCircle(c.X, c.Y, radius, paint); } public void DrawPath(SKPath path, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } if (path == null) { throw new ArgumentNullException("path"); } SkiaApi.sk_canvas_draw_path(Handle, path.Handle, paint.Handle); } public unsafe void DrawPoints(SKPointMode mode, SKPoint[] points, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } if (points == null) { throw new ArgumentNullException("points"); } fixed (SKPoint* param = points) { SkiaApi.sk_canvas_draw_points(Handle, mode, (IntPtr)points.Length, param, paint.Handle); } } public void DrawPoint(SKPoint p, SKPaint paint) { DrawPoint(p.X, p.Y, paint); } public void DrawPoint(float x, float y, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_point(Handle, x, y, paint.Handle); } public void DrawPoint(SKPoint p, SKColor color) { DrawPoint(p.X, p.Y, color); } public void DrawPoint(float x, float y, SKColor color) { using SKPaint paint = new SKPaint { Color = color, BlendMode = SKBlendMode.Src }; DrawPoint(x, y, paint); } public void DrawImage(SKImage image, SKPoint p, SKPaint paint = null) { DrawImage(image, p.X, p.Y, paint); } public void DrawImage(SKImage image, float x, float y, SKPaint paint = null) { if (image == null) { throw new ArgumentNullException("image"); } SkiaApi.sk_canvas_draw_image(Handle, image.Handle, x, y, paint?.Handle ?? IntPtr.Zero); } public unsafe void DrawImage(SKImage image, SKRect dest, SKPaint paint = null) { if (image == null) { throw new ArgumentNullException("image"); } SkiaApi.sk_canvas_draw_image_rect(Handle, image.Handle, null, &dest, paint?.Handle ?? IntPtr.Zero); } public unsafe void DrawImage(SKImage image, SKRect source, SKRect dest, SKPaint paint = null) { if (image == null) { throw new ArgumentNullException("image"); } SkiaApi.sk_canvas_draw_image_rect(Handle, image.Handle, &source, &dest, paint?.Handle ?? IntPtr.Zero); } public void DrawPicture(SKPicture picture, float x, float y, SKPaint paint = null) { SKMatrix matrix = SKMatrix.CreateTranslation(x, y); DrawPicture(picture, ref matrix, paint); } public void DrawPicture(SKPicture picture, SKPoint p, SKPaint paint = null) { DrawPicture(picture, p.X, p.Y, paint); } public unsafe void DrawPicture(SKPicture picture, ref SKMatrix matrix, SKPaint paint = null) { if (picture == null) { throw new ArgumentNullException("picture"); } fixed (SKMatrix* param = &matrix) { SkiaApi.sk_canvas_draw_picture(Handle, picture.Handle, param, paint?.Handle ?? IntPtr.Zero); } } public unsafe void DrawPicture(SKPicture picture, SKPaint paint = null) { if (picture == null) { throw new ArgumentNullException("picture"); } SkiaApi.sk_canvas_draw_picture(Handle, picture.Handle, null, paint?.Handle ?? IntPtr.Zero); } public unsafe void DrawDrawable(SKDrawable drawable, ref SKMatrix matrix) { if (drawable == null) { throw new ArgumentNullException("drawable"); } fixed (SKMatrix* param = &matrix) { SkiaApi.sk_canvas_draw_drawable(Handle, drawable.Handle, param); } } public void DrawDrawable(SKDrawable drawable, float x, float y) { if (drawable == null) { throw new ArgumentNullException("drawable"); } SKMatrix matrix = SKMatrix.CreateTranslation(x, y); DrawDrawable(drawable, ref matrix); } public void DrawDrawable(SKDrawable drawable, SKPoint p) { if (drawable == null) { throw new ArgumentNullException("drawable"); } SKMatrix matrix = SKMatrix.CreateTranslation(p.X, p.Y); DrawDrawable(drawable, ref matrix); } public void DrawBitmap(SKBitmap bitmap, SKPoint p, SKPaint paint = null) { DrawBitmap(bitmap, p.X, p.Y, paint); } public void DrawBitmap(SKBitmap bitmap, float x, float y, SKPaint paint = null) { using SKImage image = SKImage.FromBitmap(bitmap); DrawImage(image, x, y, paint); } public void DrawBitmap(SKBitmap bitmap, SKRect dest, SKPaint paint = null) { using SKImage image = SKImage.FromBitmap(bitmap); DrawImage(image, dest, paint); } public void DrawBitmap(SKBitmap bitmap, SKRect source, SKRect dest, SKPaint paint = null) { using SKImage image = SKImage.FromBitmap(bitmap); DrawImage(image, source, dest, paint); } public void DrawSurface(SKSurface surface, SKPoint p, SKPaint paint = null) { DrawSurface(surface, p.X, p.Y, paint); } public void DrawSurface(SKSurface surface, float x, float y, SKPaint paint = null) { if (surface == null) { throw new ArgumentNullException("surface"); } surface.Draw(this, x, y, paint); } public void DrawText(SKTextBlob text, float x, float y, SKPaint paint) { if (text == null) { throw new ArgumentNullException("text"); } if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_text_blob(Handle, text.Handle, x, y, paint.Handle); } public void DrawText(string text, SKPoint p, SKPaint paint) { DrawText(text, p.X, p.Y, paint); } public void DrawText(string text, float x, float y, SKPaint paint) { DrawText(text, x, y, paint.GetFont(), paint); } public void DrawText(string text, float x, float y, SKFont font, SKPaint paint) { if (text == null) { throw new ArgumentNullException("text"); } if (font == null) { throw new ArgumentNullException("font"); } if (paint == null) { throw new ArgumentNullException("paint"); } if (paint.TextAlign != SKTextAlign.Left) { float num = font.MeasureText(text); if (paint.TextAlign == SKTextAlign.Center) { num *= 0.5f; } x -= num; } using SKTextBlob sKTextBlob = SKTextBlob.Create(text, font); if (sKTextBlob != null) { DrawText(sKTextBlob, x, y, paint); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawText(SKTextBlob, float, float, SKPaint) instead.")] public void DrawText(byte[] text, SKPoint p, SKPaint paint) { DrawText(text, p.X, p.Y, paint); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawText(SKTextBlob, float, float, SKPaint) instead.")] public void DrawText(byte[] text, float x, float y, SKPaint paint) { if (text == null) { throw new ArgumentNullException("text"); } if (paint == null) { throw new ArgumentNullException("paint"); } if (paint.TextAlign != SKTextAlign.Left) { float num = paint.MeasureText(text); if (paint.TextAlign == SKTextAlign.Center) { num *= 0.5f; } x -= num; } using SKTextBlob sKTextBlob = SKTextBlob.Create(text, paint.TextEncoding, paint.GetFont()); if (sKTextBlob != null) { DrawText(sKTextBlob, x, y, paint); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawText(SKTextBlob, float, float, SKPaint) instead.")] public void DrawText(IntPtr buffer, int length, SKPoint p, SKPaint paint) { DrawText(buffer, length, p.X, p.Y, paint); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawText(SKTextBlob, float, float, SKPaint) instead.")] public void DrawText(IntPtr buffer, int length, float x, float y, SKPaint paint) { if (buffer == IntPtr.Zero && length != 0) { throw new ArgumentNullException("buffer"); } if (paint == null) { throw new ArgumentNullException("paint"); } if (paint.TextAlign != SKTextAlign.Left) { float num = paint.MeasureText(buffer, length); if (paint.TextAlign == SKTextAlign.Center) { num *= 0.5f; } x -= num; } using SKTextBlob sKTextBlob = SKTextBlob.Create(buffer, length, paint.TextEncoding, paint.GetFont()); if (sKTextBlob != null) { DrawText(sKTextBlob, x, y, paint); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawText(SKTextBlob, float, float, SKPaint) instead.")] public void DrawPositionedText(string text, SKPoint[] points, SKPaint paint) { if (text == null) { throw new ArgumentNullException("text"); } if (paint == null) { throw new ArgumentNullException("paint"); } if (points == null) { throw new ArgumentNullException("points"); } using SKTextBlob sKTextBlob = SKTextBlob.CreatePositioned(text, paint.GetFont(), points); if (sKTextBlob != null) { DrawText(sKTextBlob, 0f, 0f, paint); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawText(SKTextBlob, float, float, SKPaint) instead.")] public void DrawPositionedText(byte[] text, SKPoint[] points, SKPaint paint) { if (text == null) { throw new ArgumentNullException("text"); } if (paint == null) { throw new ArgumentNullException("paint"); } if (points == null) { throw new ArgumentNullException("points"); } using SKTextBlob sKTextBlob = SKTextBlob.CreatePositioned(text, paint.TextEncoding, paint.GetFont(), points); if (sKTextBlob != null) { DrawText(sKTextBlob, 0f, 0f, paint); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawText(SKTextBlob, float, float, SKPaint) instead.")] public void DrawPositionedText(IntPtr buffer, int length, SKPoint[] points, SKPaint paint) { if (buffer == IntPtr.Zero && length != 0) { throw new ArgumentNullException("buffer"); } if (paint == null) { throw new ArgumentNullException("paint"); } if (points == null) { throw new ArgumentNullException("points"); } using SKTextBlob sKTextBlob = SKTextBlob.CreatePositioned(buffer, length, paint.TextEncoding, paint.GetFont(), points); if (sKTextBlob != null) { DrawText(sKTextBlob, 0f, 0f, paint); } } public void DrawTextOnPath(string text, SKPath path, SKPoint offset, SKPaint paint) { DrawTextOnPath(text, path, offset, warpGlyphs: true, paint); } public void DrawTextOnPath(string text, SKPath path, float hOffset, float vOffset, SKPaint paint) { DrawTextOnPath(text, path, new SKPoint(hOffset, vOffset), warpGlyphs: true, paint); } public void DrawTextOnPath(string text, SKPath path, SKPoint offset, bool warpGlyphs, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } DrawTextOnPath(text, path, offset, warpGlyphs, paint.GetFont(), paint); } public void DrawTextOnPath(string text, SKPath path, SKPoint offset, bool warpGlyphs, SKFont font, SKPaint paint) { if (text == null) { throw new ArgumentNullException("text"); } if (path == null) { throw new ArgumentNullException("path"); } if (font == null) { throw new ArgumentNullException("font"); } if (paint == null) { throw new ArgumentNullException("paint"); } if (warpGlyphs) { using (SKPath path2 = font.GetTextPathOnPath(text, path, paint.TextAlign, offset)) { DrawPath(path2, paint); return; } } using SKTextBlob sKTextBlob = SKTextBlob.CreatePathPositioned(text, font, path, paint.TextAlign, offset); if (sKTextBlob != null) { DrawText(sKTextBlob, 0f, 0f, paint); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawTextOnPath(string, SKPath, SKPoint, SKPaint) instead.")] public void DrawTextOnPath(byte[] text, SKPath path, SKPoint offset, SKPaint paint) { DrawTextOnPath(text, path, offset.X, offset.Y, paint); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawTextOnPath(string, SKPath, float, float, SKPaint) instead.")] public unsafe void DrawTextOnPath(byte[] text, SKPath path, float hOffset, float vOffset, SKPaint paint) { if (text == null) { throw new ArgumentNullException("text"); } if (path == null) { throw new ArgumentNullException("path"); } if (paint == null) { throw new ArgumentNullException("paint"); } fixed (byte* ptr = text) { DrawTextOnPath((IntPtr)ptr, text.Length, path, hOffset, vOffset, paint); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawTextOnPath(string, SKPath, SKPoint, SKPaint) instead.")] public void DrawTextOnPath(IntPtr buffer, int length, SKPath path, SKPoint offset, SKPaint paint) { DrawTextOnPath(buffer, length, path, offset.X, offset.Y, paint); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use DrawTextOnPath(string, SKPath, float, float, SKPaint) instead.")] public void DrawTextOnPath(IntPtr buffer, int length, SKPath path, float hOffset, float vOffset, SKPaint paint) { if (buffer == IntPtr.Zero && length != 0) { throw new ArgumentNullException("buffer"); } if (path == null) { throw new ArgumentNullException("path"); } if (paint == null) { throw new ArgumentNullException("paint"); } SKFont font = paint.GetFont(); using SKPath path2 = font.GetTextPathOnPath(buffer, length, paint.TextEncoding, path, paint.TextAlign, new SKPoint(hOffset, vOffset)); DrawPath(path2, paint); } public void Flush() { SkiaApi.sk_canvas_flush(Handle); } public unsafe void DrawAnnotation(SKRect rect, string key, SKData value) { fixed (byte* encodedText = StringUtilities.GetEncodedText(key, SKTextEncoding.Utf8, addNull: true)) { SkiaApi.sk_canvas_draw_annotation(base.Handle, &rect, encodedText, value?.Handle ?? IntPtr.Zero); } } public unsafe void DrawUrlAnnotation(SKRect rect, SKData value) { SkiaApi.sk_canvas_draw_url_annotation(Handle, &rect, value?.Handle ?? IntPtr.Zero); } public SKData DrawUrlAnnotation(SKRect rect, string value) { SKData sKData = SKData.FromCString(value); DrawUrlAnnotation(rect, sKData); return sKData; } public unsafe void DrawNamedDestinationAnnotation(SKPoint point, SKData value) { SkiaApi.sk_canvas_draw_named_destination_annotation(Handle, &point, value?.Handle ?? IntPtr.Zero); } public SKData DrawNamedDestinationAnnotation(SKPoint point, string value) { SKData sKData = SKData.FromCString(value); DrawNamedDestinationAnnotation(point, sKData); return sKData; } public unsafe void DrawLinkDestinationAnnotation(SKRect rect, SKData value) { SkiaApi.sk_canvas_draw_link_destination_annotation(Handle, &rect, value?.Handle ?? IntPtr.Zero); } public SKData DrawLinkDestinationAnnotation(SKRect rect, string value) { SKData sKData = SKData.FromCString(value); DrawLinkDestinationAnnotation(rect, sKData); return sKData; } public void DrawBitmapNinePatch(SKBitmap bitmap, SKRectI center, SKRect dst, SKPaint paint = null) { using SKImage image = SKImage.FromBitmap(bitmap); DrawImageNinePatch(image, center, dst, paint); } public unsafe void DrawImageNinePatch(SKImage image, SKRectI center, SKRect dst, SKPaint paint = null) { if (image == null) { throw new ArgumentNullException("image"); } if (!SKRect.Create(image.Width, image.Height).Contains(center)) { throw new ArgumentException("Center rectangle must be contained inside the image bounds.", "center"); } SkiaApi.sk_canvas_draw_image_nine(Handle, image.Handle, ¢er, &dst, paint?.Handle ?? IntPtr.Zero); } public void DrawBitmapLattice(SKBitmap bitmap, int[] xDivs, int[] yDivs, SKRect dst, SKPaint paint = null) { using SKImage image = SKImage.FromBitmap(bitmap); DrawImageLattice(image, xDivs, yDivs, dst, paint); } public void DrawImageLattice(SKImage image, int[] xDivs, int[] yDivs, SKRect dst, SKPaint paint = null) { SKLattice lattice = new SKLattice { XDivs = xDivs, YDivs = yDivs }; DrawImageLattice(image, lattice, dst, paint); } public void DrawBitmapLattice(SKBitmap bitmap, SKLattice lattice, SKRect dst, SKPaint paint = null) { using SKImage image = SKImage.FromBitmap(bitmap); DrawImageLattice(image, lattice, dst, paint); } public unsafe void DrawImageLattice(SKImage image, SKLattice lattice, SKRect dst, SKPaint paint = null) { if (image == null) { throw new ArgumentNullException("image"); } if (lattice.XDivs == null) { throw new ArgumentNullException("XDivs"); } if (lattice.YDivs == null) { throw new ArgumentNullException("YDivs"); } fixed (int* xDivs = lattice.XDivs) { fixed (int* yDivs = lattice.YDivs) { fixed (SKLatticeRectType* rectTypes = lattice.RectTypes) { fixed (SKColor* colors = lattice.Colors) { SKLatticeInternal sKLatticeInternal = new SKLatticeInternal { fBounds = null, fRectTypes = rectTypes, fXCount = lattice.XDivs.Length, fXDivs = xDivs, fYCount = lattice.YDivs.Length, fYDivs = yDivs, fColors = (uint*)colors }; if (lattice.Bounds.HasValue) { SKRectI value = lattice.Bounds.Value; sKLatticeInternal.fBounds = &value; } SkiaApi.sk_canvas_draw_image_lattice(Handle, image.Handle, &sKLatticeInternal, &dst, paint?.Handle ?? IntPtr.Zero); } } } } } public void ResetMatrix() { SkiaApi.sk_canvas_reset_matrix(Handle); } public unsafe void SetMatrix(SKMatrix matrix) { SkiaApi.sk_canvas_set_matrix(Handle, &matrix); } public void DrawVertices(SKVertexMode vmode, SKPoint[] vertices, SKColor[] colors, SKPaint paint) { SKVertices vertices2 = SKVertices.CreateCopy(vmode, vertices, colors); DrawVertices(vertices2, SKBlendMode.Modulate, paint); } public void DrawVertices(SKVertexMode vmode, SKPoint[] vertices, SKPoint[] texs, SKColor[] colors, SKPaint paint) { SKVertices vertices2 = SKVertices.CreateCopy(vmode, vertices, texs, colors); DrawVertices(vertices2, SKBlendMode.Modulate, paint); } public void DrawVertices(SKVertexMode vmode, SKPoint[] vertices, SKPoint[] texs, SKColor[] colors, ushort[] indices, SKPaint paint) { SKVertices vertices2 = SKVertices.CreateCopy(vmode, vertices, texs, colors, indices); DrawVertices(vertices2, SKBlendMode.Modulate, paint); } public void DrawVertices(SKVertexMode vmode, SKPoint[] vertices, SKPoint[] texs, SKColor[] colors, SKBlendMode mode, ushort[] indices, SKPaint paint) { SKVertices vertices2 = SKVertices.CreateCopy(vmode, vertices, texs, colors, indices); DrawVertices(vertices2, mode, paint); } public void DrawVertices(SKVertices vertices, SKBlendMode mode, SKPaint paint) { if (vertices == null) { throw new ArgumentNullException("vertices"); } if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_vertices(Handle, vertices.Handle, mode, paint.Handle); } public unsafe void DrawArc(SKRect oval, float startAngle, float sweepAngle, bool useCenter, SKPaint paint) { if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_arc(Handle, &oval, startAngle, sweepAngle, useCenter, paint.Handle); } public void DrawRoundRectDifference(SKRoundRect outer, SKRoundRect inner, SKPaint paint) { if (outer == null) { throw new ArgumentNullException("outer"); } if (inner == null) { throw new ArgumentNullException("inner"); } if (paint == null) { throw new ArgumentNullException("paint"); } SkiaApi.sk_canvas_draw_drrect(Handle, outer.Handle, inner.Handle, paint.Handle); } public unsafe void DrawAtlas(SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKPaint paint) { DrawAtlas(atlas, sprites, transforms, null, SKBlendMode.Dst, null, paint); } public unsafe void DrawAtlas(SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKColor[] colors, SKBlendMode mode, SKPaint paint) { DrawAtlas(atlas, sprites, transforms, colors, mode, null, paint); } public unsafe void DrawAtlas(SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKColor[] colors, SKBlendMode mode, SKRect cullRect, SKPaint paint) { DrawAtlas(atlas, sprites, transforms, colors, mode, &cullRect, paint); } private unsafe void DrawAtlas(SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKColor[] colors, SKBlendMode mode, SKRect* cullRect, SKPaint paint) { if (atlas == null) { throw new ArgumentNullException("atlas"); } if (sprites == null) { throw new ArgumentNullException("sprites"); } if (transforms == null) { throw new ArgumentNullException("transforms"); } if (transforms.Length != sprites.Length) { throw new ArgumentException("The number of transforms must match the number of sprites.", "transforms"); } if (colors != null && colors.Length != sprites.Length) { throw new ArgumentException("The number of colors must match the number of sprites.", "colors"); } fixed (SKRect* tex = sprites) { fixed (SKRotationScaleMatrix* xform = transforms) { fixed (SKColor* colors2 = colors) { SkiaApi.sk_canvas_draw_atlas(Handle, atlas.Handle, xform, tex, (uint*)colors2, transforms.Length, mode, cullRect, paint.Handle); } } } } public void DrawPatch(SKPoint[] cubics, SKColor[] colors, SKPoint[] texCoords, SKPaint paint) { DrawPatch(cubics, colors, texCoords, SKBlendMode.Modulate, paint); } public unsafe void DrawPatch(SKPoint[] cubics, SKColor[] colors, SKPoint[] texCoords, SKBlendMode mode, SKPaint paint) { if (cubics == null) { throw new ArgumentNullException("cubics"); } if (cubics.Length != 12) { throw new ArgumentException($"Cubics must have a length of {12}.", "cubics"); } if (colors != null && colors.Length != 4) { throw new ArgumentException($"Colors must have a length of {4}.", "colors"); } if (texCoords != null && texCoords.Length != 4) { throw new ArgumentException($"Texture coordinates must have a length of {4}.", "texCoords"); } if (paint == null) { throw new ArgumentNullException("paint"); } fixed (SKPoint* cubics2 = cubics) { fixed (SKColor* colors2 = colors) { fixed (SKPoint* texCoords2 = texCoords) { SkiaApi.sk_canvas_draw_patch(Handle, cubics2, (uint*)colors2, texCoords2, mode, paint.Handle); } } } } internal static SKCanvas GetObject(IntPtr handle, bool owns = true, bool unrefExisting = true) { return SKObject.GetOrAddObject(handle, owns, unrefExisting, (IntPtr h, bool o) => new SKCanvas(h, o)); } } public class SKAutoCanvasRestore : IDisposable { private SKCanvas canvas; private readonly int saveCount; public SKAutoCanvasRestore(SKCanvas canvas) : this(canvas, doSave: true) { } public SKAutoCanvasRestore(SKCanvas canvas, bool doSave) { this.canvas = canvas; saveCount = 0; if (canvas != null) { saveCount = canvas.SaveCount; if (doSave) { canvas.Save(); } } } public void Dispose() { Restore(); } public void Restore() { if (canvas != null) { canvas.RestoreToCount(saveCount); canvas = null; } } } public class SKCodec : SKObject, ISKSkipObjectRegistration { public static int MinBufferedBytesNeeded => (int)SkiaApi.sk_codec_min_buffered_bytes_needed(); public unsafe SKImageInfo Info { get { SKImageInfoNative native = default(SKImageInfoNative); SkiaApi.sk_codec_get_info(Handle, &native); return SKImageInfoNative.ToManaged(ref native); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use EncodedOrigin instead.")] public SKCodecOrigin Origin => (SKCodecOrigin)EncodedOrigin; public SKEncodedOrigin EncodedOrigin => SkiaApi.sk_codec_get_origin(Handle); public SKEncodedImageFormat EncodedFormat => SkiaApi.sk_codec_get_encoded_format(Handle); public byte[] Pixels { get { byte[] pixels2; SKCodecResult pixels = GetPixels(out pixels2); if (pixels != SKCodecResult.Success && pixels != SKCodecResult.IncompleteInput) { throw new Exception(pixels.ToString()); } return pixels2; } } public int RepetitionCount => SkiaApi.sk_codec_get_repetition_count(Handle); public int FrameCount => SkiaApi.sk_codec_get_frame_count(Handle); public unsafe SKCodecFrameInfo[] FrameInfo { get { int num = SkiaApi.sk_codec_get_frame_count(Handle); SKCodecFrameInfo[] array = new SKCodecFrameInfo[num]; fixed (SKCodecFrameInfo* frameInfo = array) { SkiaApi.sk_codec_get_frame_info(Handle, frameInfo); } return array; } } public SKCodecScanlineOrder ScanlineOrder => SkiaApi.sk_codec_get_scanline_order(Handle); public int NextScanline => SkiaApi.sk_codec_next_scanline(Handle); internal SKCodec(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_codec_destroy(Handle); } public unsafe SKSizeI GetScaledDimensions(float desiredScale) { SKSizeI result = default(SKSizeI); SkiaApi.sk_codec_get_scaled_dimensions(Handle, desiredScale, &result); return result; } public unsafe bool GetValidSubset(ref SKRectI desiredSubset) { fixed (SKRectI* desiredSubset2 = &desiredSubset) { return SkiaApi.sk_codec_get_valid_subset(Handle, desiredSubset2); } } public unsafe bool GetFrameInfo(int index, out SKCodecFrameInfo frameInfo) { fixed (SKCodecFrameInfo* frameInfo2 = &frameInfo) { return SkiaApi.sk_codec_get_frame_info_for_index(Handle, index, frameInfo2); } } public SKCodecResult GetPixels(out byte[] pixels) { return GetPixels(Info, out pixels); } public SKCodecResult GetPixels(SKImageInfo info, out byte[] pixels) { pixels = new byte[info.BytesSize]; return GetPixels(info, pixels); } public unsafe SKCodecResult GetPixels(SKImageInfo info, byte[] pixels) { if (pixels == null) { throw new ArgumentNullException("pixels"); } fixed (byte* ptr = pixels) { return GetPixels(info, (IntPtr)ptr, info.RowBytes, SKCodecOptions.Default); } } public SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels) { return GetPixels(info, pixels, info.RowBytes, SKCodecOptions.Default); } public SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels, SKCodecOptions options) { return GetPixels(info, pixels, info.RowBytes, options); } public unsafe SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels, int rowBytes, SKCodecOptions options) { if (pixels == IntPtr.Zero) { throw new ArgumentNullException("pixels"); } SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); SKCodecOptionsInternal sKCodecOptionsInternal = new SKCodecOptionsInternal { fZeroInitialized = options.ZeroInitialized, fSubset = null, fFrameIndex = options.FrameIndex, fPriorFrame = options.PriorFrame }; SKRectI sKRectI = default(SKRectI); if (options.HasSubset) { sKRectI = options.Subset.Value; sKCodecOptionsInternal.fSubset = &sKRectI; } return SkiaApi.sk_codec_get_pixels(Handle, &sKImageInfoNative, (void*)pixels, (IntPtr)rowBytes, &sKCodecOptionsInternal); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use GetPixels(SKImageInfo, IntPtr, int, SKCodecOptions) instead.")] public SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels, int rowBytes, SKCodecOptions options, IntPtr colorTable, ref int colorTableCount) { return GetPixels(info, pixels, rowBytes, options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use GetPixels(SKImageInfo, IntPtr, SKCodecOptions) instead.")] public SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels, SKCodecOptions options, IntPtr colorTable, ref int colorTableCount) { return GetPixels(info, pixels, info.RowBytes, options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use GetPixels(SKImageInfo, IntPtr) instead.")] public SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels, IntPtr colorTable, ref int colorTableCount) { return GetPixels(info, pixels, info.RowBytes, SKCodecOptions.Default); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use GetPixels(SKImageInfo, IntPtr, int, SKCodecOptions) instead.")] public SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels, int rowBytes, SKCodecOptions options, SKColorTable colorTable, ref int colorTableCount) { return GetPixels(info, pixels, rowBytes, options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use GetPixels(SKImageInfo, IntPtr, SKCodecOptions) instead.")] public SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels, SKCodecOptions options, SKColorTable colorTable, ref int colorTableCount) { return GetPixels(info, pixels, info.RowBytes, options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use GetPixels(SKImageInfo, IntPtr) instead.")] public SKCodecResult GetPixels(SKImageInfo info, IntPtr pixels, SKColorTable colorTable, ref int colorTableCount) { return GetPixels(info, pixels, info.RowBytes, SKCodecOptions.Default); } public unsafe SKCodecResult StartIncrementalDecode(SKImageInfo info, IntPtr pixels, int rowBytes, SKCodecOptions options) { if (pixels == IntPtr.Zero) { throw new ArgumentNullException("pixels"); } SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); SKCodecOptionsInternal sKCodecOptionsInternal = new SKCodecOptionsInternal { fZeroInitialized = options.ZeroInitialized, fSubset = null, fFrameIndex = options.FrameIndex, fPriorFrame = options.PriorFrame }; SKRectI sKRectI = default(SKRectI); if (options.HasSubset) { sKRectI = options.Subset.Value; sKCodecOptionsInternal.fSubset = &sKRectI; } return SkiaApi.sk_codec_start_incremental_decode(Handle, &sKImageInfoNative, (void*)pixels, (IntPtr)rowBytes, &sKCodecOptionsInternal); } public unsafe SKCodecResult StartIncrementalDecode(SKImageInfo info, IntPtr pixels, int rowBytes) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return SkiaApi.sk_codec_start_incremental_decode(Handle, &sKImageInfoNative, (void*)pixels, (IntPtr)rowBytes, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use StartIncrementalDecode(SKImageInfo, IntPtr, int, SKCodecOptions) instead.")] public SKCodecResult StartIncrementalDecode(SKImageInfo info, IntPtr pixels, int rowBytes, SKCodecOptions options, IntPtr colorTable, ref int colorTableCount) { return StartIncrementalDecode(info, pixels, rowBytes, options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use StartIncrementalDecode(SKImageInfo, IntPtr, int, SKCodecOptions) instead.")] public SKCodecResult StartIncrementalDecode(SKImageInfo info, IntPtr pixels, int rowBytes, SKCodecOptions options, SKColorTable colorTable, ref int colorTableCount) { return StartIncrementalDecode(info, pixels, rowBytes, options); } public unsafe SKCodecResult IncrementalDecode(out int rowsDecoded) { fixed (int* rowsDecoded2 = &rowsDecoded) { return SkiaApi.sk_codec_incremental_decode(Handle, rowsDecoded2); } } public unsafe SKCodecResult IncrementalDecode() { return SkiaApi.sk_codec_incremental_decode(Handle, null); } public unsafe SKCodecResult StartScanlineDecode(SKImageInfo info, SKCodecOptions options) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); SKCodecOptionsInternal sKCodecOptionsInternal = new SKCodecOptionsInternal { fZeroInitialized = options.ZeroInitialized, fSubset = null, fFrameIndex = options.FrameIndex, fPriorFrame = options.PriorFrame }; SKRectI sKRectI = default(SKRectI); if (options.HasSubset) { sKRectI = options.Subset.Value; sKCodecOptionsInternal.fSubset = &sKRectI; } return SkiaApi.sk_codec_start_scanline_decode(Handle, &sKImageInfoNative, &sKCodecOptionsInternal); } public unsafe SKCodecResult StartScanlineDecode(SKImageInfo info) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return SkiaApi.sk_codec_start_scanline_decode(Handle, &sKImageInfoNative, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use StartScanlineDecode(SKImageInfo, SKCodecOptions) instead.")] public SKCodecResult StartScanlineDecode(SKImageInfo info, SKCodecOptions options, IntPtr colorTable, ref int colorTableCount) { return StartScanlineDecode(info, options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use StartScanlineDecode(SKImageInfo, SKCodecOptions) instead.")] public SKCodecResult StartScanlineDecode(SKImageInfo info, SKCodecOptions options, SKColorTable colorTable, ref int colorTableCount) { return StartScanlineDecode(info, options); } public unsafe int GetScanlines(IntPtr dst, int countLines, int rowBytes) { if (dst == IntPtr.Zero) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_codec_get_scanlines(Handle, (void*)dst, countLines, (IntPtr)rowBytes); } public bool SkipScanlines(int countLines) { return SkiaApi.sk_codec_skip_scanlines(Handle, countLines); } public int GetOutputScanline(int inputScanline) { return SkiaApi.sk_codec_output_scanline(Handle, inputScanline); } public static SKCodec Create(string filename) { SKCodecResult result; return Create(filename, out result); } public static SKCodec Create(string filename, out SKCodecResult result) { SKStreamAsset sKStreamAsset = SKFileStream.OpenStream(filename); if (sKStreamAsset == null) { result = SKCodecResult.InternalError; return null; } return Create(sKStreamAsset, out result); } public static SKCodec Create(Stream stream) { SKCodecResult result; return Create(stream, out result); } public static SKCodec Create(Stream stream, out SKCodecResult result) { return Create(WrapManagedStream(stream), out result); } public static SKCodec Create(SKStream stream) { SKCodecResult result; return Create(stream, out result); } public unsafe static SKCodec Create(SKStream stream, out SKCodecResult result) { if (stream == null) { throw new ArgumentNullException("stream"); } if (stream is SKFileStream { IsValid: false }) { throw new ArgumentException("File stream was not valid.", "stream"); } fixed (SKCodecResult* result2 = &result) { SKCodec sKCodec = GetObject(SkiaApi.sk_codec_new_from_stream(stream.Handle, result2)); stream.RevokeOwnership(sKCodec); return sKCodec; } } public static SKCodec Create(SKData data) { if (data == null) { throw new ArgumentNullException("data"); } return GetObject(SkiaApi.sk_codec_new_from_data(data.Handle)); } internal static SKStream WrapManagedStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } if (stream.CanSeek) { return new SKManagedStream(stream, disposeManagedStream: true); } return new SKFrontBufferedManagedStream(stream, MinBufferedBytesNeeded, disposeUnderlyingStream: true); } internal static SKCodec GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new SKCodec(handle, owns: true); } return null; } } public readonly struct SKColor : IEquatable { public static readonly SKColor Empty; private readonly uint color; public byte Alpha => (byte)((color >> 24) & 0xFF); public byte Red => (byte)((color >> 16) & 0xFF); public byte Green => (byte)((color >> 8) & 0xFF); public byte Blue => (byte)(color & 0xFF); public float Hue { get { ToHsv(out var h, out var _, out var _); return h; } } public SKColor(uint value) { color = value; } public SKColor(byte red, byte green, byte blue, byte alpha) { color = (uint)((alpha << 24) | (red << 16) | (green << 8) | blue); } public SKColor(byte red, byte green, byte blue) { color = (uint)(-16777216 | (red << 16) | (green << 8) | blue); } public SKColor WithRed(byte red) { return new SKColor(red, Green, Blue, Alpha); } public SKColor WithGreen(byte green) { return new SKColor(Red, green, Blue, Alpha); } public SKColor WithBlue(byte blue) { return new SKColor(Red, Green, blue, Alpha); } public SKColor WithAlpha(byte alpha) { return new SKColor(Red, Green, Blue, alpha); } public static SKColor FromHsl(float h, float s, float l, byte a = byte.MaxValue) { SKColorF sKColorF = SKColorF.FromHsl(h, s, l); float num = sKColorF.Red * 255f; float num2 = sKColorF.Green * 255f; float num3 = sKColorF.Blue * 255f; return new SKColor((byte)num, (byte)num2, (byte)num3, a); } public static SKColor FromHsv(float h, float s, float v, byte a = byte.MaxValue) { SKColorF sKColorF = SKColorF.FromHsv(h, s, v); float num = sKColorF.Red * 255f; float num2 = sKColorF.Green * 255f; float num3 = sKColorF.Blue * 255f; return new SKColor((byte)num, (byte)num2, (byte)num3, a); } public void ToHsl(out float h, out float s, out float l) { float red = (float)(int)Red / 255f; float green = (float)(int)Green / 255f; float blue = (float)(int)Blue / 255f; new SKColorF(red, green, blue).ToHsl(out h, out s, out l); } public void ToHsv(out float h, out float s, out float v) { float red = (float)(int)Red / 255f; float green = (float)(int)Green / 255f; float blue = (float)(int)Blue / 255f; new SKColorF(red, green, blue).ToHsv(out h, out s, out v); } public override string ToString() { return $"#{Alpha:x2}{Red:x2}{Green:x2}{Blue:x2}"; } public bool Equals(SKColor obj) { return obj.color == color; } public override bool Equals(object other) { if (other is SKColor obj) { return Equals(obj); } return false; } public static bool operator ==(SKColor left, SKColor right) { return left.Equals(right); } public static bool operator !=(SKColor left, SKColor right) { return !left.Equals(right); } public override int GetHashCode() { uint num = color; return num.GetHashCode(); } public static implicit operator SKColor(uint color) { return new SKColor(color); } public static explicit operator uint(SKColor color) { return color.color; } public static SKColor Parse(string hexString) { if (!TryParse(hexString, out var result)) { throw new ArgumentException("Invalid hexadecimal color string.", "hexString"); } return result; } public static bool TryParse(string hexString, out SKColor color) { if (string.IsNullOrWhiteSpace(hexString)) { color = Empty; return false; } hexString = hexString.Trim(); int num = ((hexString[0] == '#') ? 1 : 0); int num2 = hexString.Length - num; switch (num2) { case 3: case 4: { byte result2; if (num2 == 4) { if (!byte.TryParse(string.Concat(new string(hexString[num2 - 4 + num], 2)), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out result2)) { color = Empty; return false; } } else { result2 = byte.MaxValue; } if (!byte.TryParse(new string(hexString[num2 - 3 + num], 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result3) || !byte.TryParse(new string(hexString[num2 - 2 + num], 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result4) || !byte.TryParse(new string(hexString[num2 - 1 + num], 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result5)) { color = Empty; return false; } color = new SKColor(result3, result4, result5, result2); return true; } case 6: case 8: { if (!uint.TryParse(hexString.Substring(num), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result)) { color = Empty; return false; } color = result; if (num2 == 6) { color = color.WithAlpha(byte.MaxValue); } return true; } default: color = Empty; return false; } } } public readonly struct SKColorF : IEquatable { private const float EPSILON = 0.001f; public static readonly SKColorF Empty; private readonly float fR; private readonly float fG; private readonly float fB; private readonly float fA; public float Hue { get { ToHsv(out var h, out var _, out var _); return h; } } public float Red => fR; public float Green => fG; public float Blue => fB; public float Alpha => fA; public SKColorF(float red, float green, float blue) { fR = red; fG = green; fB = blue; fA = 1f; } public SKColorF(float red, float green, float blue, float alpha) { fR = red; fG = green; fB = blue; fA = alpha; } public SKColorF WithRed(float red) { return new SKColorF(red, fG, fB, fA); } public SKColorF WithGreen(float green) { return new SKColorF(fR, green, fB, fA); } public SKColorF WithBlue(float blue) { return new SKColorF(fR, fG, blue, fA); } public SKColorF WithAlpha(float alpha) { return new SKColorF(fR, fG, fB, alpha); } public SKColorF Clamp() { return new SKColorF(Clamp(fR), Clamp(fG), Clamp(fB), Clamp(fA)); static float Clamp(float v) { if (v > 1f) { return 1f; } if (v < 0f) { return 0f; } return v; } } public static SKColorF FromHsl(float h, float s, float l, float a = 1f) { h /= 360f; s /= 100f; l /= 100f; float red = l; float green = l; float blue = l; if (Math.Abs(s) > 0.001f) { float num = ((!(l < 0.5f)) ? (l + s - s * l) : (l * (1f + s))); float v = 2f * l - num; red = HueToRgb(v, num, h + 1f / 3f); green = HueToRgb(v, num, h); blue = HueToRgb(v, num, h - 1f / 3f); } return new SKColorF(red, green, blue, a); } private static float HueToRgb(float v1, float v2, float vH) { if (vH < 0f) { vH += 1f; } if (vH > 1f) { vH -= 1f; } if (6f * vH < 1f) { return v1 + (v2 - v1) * 6f * vH; } if (2f * vH < 1f) { return v2; } if (3f * vH < 2f) { return v1 + (v2 - v1) * (2f / 3f - vH) * 6f; } return v1; } public static SKColorF FromHsv(float h, float s, float v, float a = 1f) { h /= 360f; s /= 100f; v /= 100f; float red = v; float green = v; float blue = v; if (Math.Abs(s) > 0.001f) { h *= 6f; if (Math.Abs(h - 6f) < 0.001f) { h = 0f; } int num = (int)h; float num2 = v * (1f - s); float num3 = v * (1f - s * (h - (float)num)); float num4 = v * (1f - s * (1f - (h - (float)num))); switch (num) { case 0: red = v; green = num4; blue = num2; break; case 1: red = num3; green = v; blue = num2; break; case 2: red = num2; green = v; blue = num4; break; case 3: red = num2; green = num3; blue = v; break; case 4: red = num4; green = num2; blue = v; break; default: red = v; green = num2; blue = num3; break; } } return new SKColorF(red, green, blue, a); } public void ToHsl(out float h, out float s, out float l) { float num = fR; float num2 = fG; float num3 = fB; float num4 = Math.Min(Math.Min(num, num2), num3); float num5 = Math.Max(Math.Max(num, num2), num3); float num6 = num5 - num4; h = 0f; s = 0f; l = (num5 + num4) / 2f; if (Math.Abs(num6) > 0.001f) { if (l < 0.5f) { s = num6 / (num5 + num4); } else { s = num6 / (2f - num5 - num4); } float num7 = ((num5 - num) / 6f + num6 / 2f) / num6; float num8 = ((num5 - num2) / 6f + num6 / 2f) / num6; float num9 = ((num5 - num3) / 6f + num6 / 2f) / num6; if (Math.Abs(num - num5) < 0.001f) { h = num9 - num8; } else if (Math.Abs(num2 - num5) < 0.001f) { h = 1f / 3f + num7 - num9; } else { h = 2f / 3f + num8 - num7; } if (h < 0f) { h += 1f; } if (h > 1f) { h -= 1f; } } h *= 360f; s *= 100f; l *= 100f; } public void ToHsv(out float h, out float s, out float v) { float num = fR; float num2 = fG; float num3 = fB; float num4 = Math.Min(Math.Min(num, num2), num3); float num5 = Math.Max(Math.Max(num, num2), num3); float num6 = num5 - num4; h = 0f; s = 0f; v = num5; if (Math.Abs(num6) > 0.001f) { s = num6 / num5; float num7 = ((num5 - num) / 6f + num6 / 2f) / num6; float num8 = ((num5 - num2) / 6f + num6 / 2f) / num6; float num9 = ((num5 - num3) / 6f + num6 / 2f) / num6; if (Math.Abs(num - num5) < 0.001f) { h = num9 - num8; } else if (Math.Abs(num2 - num5) < 0.001f) { h = 1f / 3f + num7 - num9; } else { h = 2f / 3f + num8 - num7; } if (h < 0f) { h += 1f; } if (h > 1f) { h -= 1f; } } h *= 360f; s *= 100f; v *= 100f; } public override string ToString() { return ((SKColor)this).ToString(); } public unsafe static implicit operator SKColorF(SKColor color) { SKColorF result = default(SKColorF); SkiaApi.sk_color4f_from_color((uint)color, &result); return result; } public unsafe static explicit operator SKColor(SKColorF color) { return SkiaApi.sk_color4f_to_color(&color); } public bool Equals(SKColorF obj) { if (fR == obj.fR && fG == obj.fG && fB == obj.fB) { return fA == obj.fA; } return false; } public override bool Equals(object obj) { if (obj is SKColorF obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKColorF left, SKColorF right) { return left.Equals(right); } public static bool operator !=(SKColorF left, SKColorF right) { return !left.Equals(right); } public override int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fR); hashCode.Add(fG); hashCode.Add(fB); hashCode.Add(fA); return hashCode.ToHashCode(); } } public class SKColorFilter : SKObject, ISKReferenceCounted { public const int ColorMatrixSize = 20; public const int TableMaxLength = 256; internal SKColorFilter(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public static SKColorFilter CreateBlendMode(SKColor c, SKBlendMode mode) { return GetObject(SkiaApi.sk_colorfilter_new_mode((uint)c, mode)); } public static SKColorFilter CreateLighting(SKColor mul, SKColor add) { return GetObject(SkiaApi.sk_colorfilter_new_lighting((uint)mul, (uint)add)); } public static SKColorFilter CreateCompose(SKColorFilter outer, SKColorFilter inner) { if (outer == null) { throw new ArgumentNullException("outer"); } if (inner == null) { throw new ArgumentNullException("inner"); } return GetObject(SkiaApi.sk_colorfilter_new_compose(outer.Handle, inner.Handle)); } public unsafe static SKColorFilter CreateColorMatrix(float[] matrix) { if (matrix == null) { throw new ArgumentNullException("matrix"); } if (matrix.Length != 20) { throw new ArgumentException("Matrix must have a length of 20.", "matrix"); } fixed (float* array = matrix) { return GetObject(SkiaApi.sk_colorfilter_new_color_matrix(array)); } } public static SKColorFilter CreateLumaColor() { return GetObject(SkiaApi.sk_colorfilter_new_luma_color()); } public unsafe static SKColorFilter CreateTable(byte[] table) { if (table == null) { throw new ArgumentNullException("table"); } if (table.Length != 256) { throw new ArgumentException($"Table must have a length of {256}.", "table"); } fixed (byte* table2 = table) { return GetObject(SkiaApi.sk_colorfilter_new_table(table2)); } } public unsafe static SKColorFilter CreateTable(byte[] tableA, byte[] tableR, byte[] tableG, byte[] tableB) { if (tableA != null && tableA.Length != 256) { throw new ArgumentException($"Table A must have a length of {256}.", "tableA"); } if (tableR != null && tableR.Length != 256) { throw new ArgumentException($"Table R must have a length of {256}.", "tableR"); } if (tableG != null && tableG.Length != 256) { throw new ArgumentException($"Table G must have a length of {256}.", "tableG"); } if (tableB != null && tableB.Length != 256) { throw new ArgumentException($"Table B must have a length of {256}.", "tableB"); } fixed (byte* tableA2 = tableA) { fixed (byte* tableR2 = tableR) { fixed (byte* tableG2 = tableG) { fixed (byte* tableB2 = tableB) { return GetObject(SkiaApi.sk_colorfilter_new_table_argb(tableA2, tableR2, tableG2, tableB2)); } } } } } public unsafe static SKColorFilter CreateHighContrast(SKHighContrastConfig config) { return GetObject(SkiaApi.sk_colorfilter_new_high_contrast(&config)); } public static SKColorFilter CreateHighContrast(bool grayscale, SKHighContrastConfigInvertStyle invertStyle, float contrast) { return CreateHighContrast(new SKHighContrastConfig(grayscale, invertStyle, contrast)); } internal static SKColorFilter GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKColorFilter(h, o)); } } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct SKColors { public static SKColor AliceBlue = new SKColor(4293982463u); public static SKColor AntiqueWhite = new SKColor(4294634455u); public static SKColor Aqua = new SKColor(4278255615u); public static SKColor Aquamarine = new SKColor(4286578644u); public static SKColor Azure = new SKColor(4293984255u); public static SKColor Beige = new SKColor(4294309340u); public static SKColor Bisque = new SKColor(4294960324u); public static SKColor Black = new SKColor(4278190080u); public static SKColor BlanchedAlmond = new SKColor(4294962125u); public static SKColor Blue = new SKColor(4278190335u); public static SKColor BlueViolet = new SKColor(4287245282u); public static SKColor Brown = new SKColor(4289014314u); public static SKColor BurlyWood = new SKColor(4292786311u); public static SKColor CadetBlue = new SKColor(4284456608u); public static SKColor Chartreuse = new SKColor(4286578432u); public static SKColor Chocolate = new SKColor(4291979550u); public static SKColor Coral = new SKColor(4294934352u); public static SKColor CornflowerBlue = new SKColor(4284782061u); public static SKColor Cornsilk = new SKColor(4294965468u); public static SKColor Crimson = new SKColor(4292613180u); public static SKColor Cyan = new SKColor(4278255615u); public static SKColor DarkBlue = new SKColor(4278190219u); public static SKColor DarkCyan = new SKColor(4278225803u); public static SKColor DarkGoldenrod = new SKColor(4290283019u); public static SKColor DarkGray = new SKColor(4289309097u); public static SKColor DarkGreen = new SKColor(4278215680u); public static SKColor DarkKhaki = new SKColor(4290623339u); public static SKColor DarkMagenta = new SKColor(4287299723u); public static SKColor DarkOliveGreen = new SKColor(4283788079u); public static SKColor DarkOrange = new SKColor(4294937600u); public static SKColor DarkOrchid = new SKColor(4288230092u); public static SKColor DarkRed = new SKColor(4287299584u); public static SKColor DarkSalmon = new SKColor(4293498490u); public static SKColor DarkSeaGreen = new SKColor(4287609995u); public static SKColor DarkSlateBlue = new SKColor(4282924427u); public static SKColor DarkSlateGray = new SKColor(4281290575u); public static SKColor DarkTurquoise = new SKColor(4278243025u); public static SKColor DarkViolet = new SKColor(4287889619u); public static SKColor DeepPink = new SKColor(4294907027u); public static SKColor DeepSkyBlue = new SKColor(4278239231u); public static SKColor DimGray = new SKColor(4285098345u); public static SKColor DodgerBlue = new SKColor(4280193279u); public static SKColor Firebrick = new SKColor(4289864226u); public static SKColor FloralWhite = new SKColor(4294966000u); public static SKColor ForestGreen = new SKColor(4280453922u); public static SKColor Fuchsia = new SKColor(4294902015u); public static SKColor Gainsboro = new SKColor(4292664540u); public static SKColor GhostWhite = new SKColor(4294506751u); public static SKColor Gold = new SKColor(4294956800u); public static SKColor Goldenrod = new SKColor(4292519200u); public static SKColor Gray = new SKColor(4286611584u); public static SKColor Green = new SKColor(4278222848u); public static SKColor GreenYellow = new SKColor(4289593135u); public static SKColor Honeydew = new SKColor(4293984240u); public static SKColor HotPink = new SKColor(4294928820u); public static SKColor IndianRed = new SKColor(4291648604u); public static SKColor Indigo = new SKColor(4283105410u); public static SKColor Ivory = new SKColor(4294967280u); public static SKColor Khaki = new SKColor(4293977740u); public static SKColor Lavender = new SKColor(4293322490u); public static SKColor LavenderBlush = new SKColor(4294963445u); public static SKColor LawnGreen = new SKColor(4286381056u); public static SKColor LemonChiffon = new SKColor(4294965965u); public static SKColor LightBlue = new SKColor(4289583334u); public static SKColor LightCoral = new SKColor(4293951616u); public static SKColor LightCyan = new SKColor(4292935679u); public static SKColor LightGoldenrodYellow = new SKColor(4294638290u); public static SKColor LightGray = new SKColor(4292072403u); public static SKColor LightGreen = new SKColor(4287688336u); public static SKColor LightPink = new SKColor(4294948545u); public static SKColor LightSalmon = new SKColor(4294942842u); public static SKColor LightSeaGreen = new SKColor(4280332970u); public static SKColor LightSkyBlue = new SKColor(4287090426u); public static SKColor LightSlateGray = new SKColor(4286023833u); public static SKColor LightSteelBlue = new SKColor(4289774814u); public static SKColor LightYellow = new SKColor(4294967264u); public static SKColor Lime = new SKColor(4278255360u); public static SKColor LimeGreen = new SKColor(4281519410u); public static SKColor Linen = new SKColor(4294635750u); public static SKColor Magenta = new SKColor(4294902015u); public static SKColor Maroon = new SKColor(4286578688u); public static SKColor MediumAquamarine = new SKColor(4284927402u); public static SKColor MediumBlue = new SKColor(4278190285u); public static SKColor MediumOrchid = new SKColor(4290401747u); public static SKColor MediumPurple = new SKColor(4287852763u); public static SKColor MediumSeaGreen = new SKColor(4282168177u); public static SKColor MediumSlateBlue = new SKColor(4286277870u); public static SKColor MediumSpringGreen = new SKColor(4278254234u); public static SKColor MediumTurquoise = new SKColor(4282962380u); public static SKColor MediumVioletRed = new SKColor(4291237253u); public static SKColor MidnightBlue = new SKColor(4279834992u); public static SKColor MintCream = new SKColor(4294311930u); public static SKColor MistyRose = new SKColor(4294960353u); public static SKColor Moccasin = new SKColor(4294960309u); public static SKColor NavajoWhite = new SKColor(4294958765u); public static SKColor Navy = new SKColor(4278190208u); public static SKColor OldLace = new SKColor(4294833638u); public static SKColor Olive = new SKColor(4286611456u); public static SKColor OliveDrab = new SKColor(4285238819u); public static SKColor Orange = new SKColor(4294944000u); public static SKColor OrangeRed = new SKColor(4294919424u); public static SKColor Orchid = new SKColor(4292505814u); public static SKColor PaleGoldenrod = new SKColor(4293847210u); public static SKColor PaleGreen = new SKColor(4288215960u); public static SKColor PaleTurquoise = new SKColor(4289720046u); public static SKColor PaleVioletRed = new SKColor(4292571283u); public static SKColor PapayaWhip = new SKColor(4294963157u); public static SKColor PeachPuff = new SKColor(4294957753u); public static SKColor Peru = new SKColor(4291659071u); public static SKColor Pink = new SKColor(4294951115u); public static SKColor Plum = new SKColor(4292714717u); public static SKColor PowderBlue = new SKColor(4289781990u); public static SKColor Purple = new SKColor(4286578816u); public static SKColor Red = new SKColor(4294901760u); public static SKColor RosyBrown = new SKColor(4290547599u); public static SKColor RoyalBlue = new SKColor(4282477025u); public static SKColor SaddleBrown = new SKColor(4287317267u); public static SKColor Salmon = new SKColor(4294606962u); public static SKColor SandyBrown = new SKColor(4294222944u); public static SKColor SeaGreen = new SKColor(4281240407u); public static SKColor SeaShell = new SKColor(4294964718u); public static SKColor Sienna = new SKColor(4288696877u); public static SKColor Silver = new SKColor(4290822336u); public static SKColor SkyBlue = new SKColor(4287090411u); public static SKColor SlateBlue = new SKColor(4285160141u); public static SKColor SlateGray = new SKColor(4285563024u); public static SKColor Snow = new SKColor(4294966010u); public static SKColor SpringGreen = new SKColor(4278255487u); public static SKColor SteelBlue = new SKColor(4282811060u); public static SKColor Tan = new SKColor(4291998860u); public static SKColor Teal = new SKColor(4278222976u); public static SKColor Thistle = new SKColor(4292394968u); public static SKColor Tomato = new SKColor(4294927175u); public static SKColor Turquoise = new SKColor(4282441936u); public static SKColor Violet = new SKColor(4293821166u); public static SKColor Wheat = new SKColor(4294303411u); public static SKColor White = new SKColor(uint.MaxValue); public static SKColor WhiteSmoke = new SKColor(4294309365u); public static SKColor Yellow = new SKColor(4294967040u); public static SKColor YellowGreen = new SKColor(4288335154u); public static SKColor Transparent = new SKColor(16777215u); public static SKColor Empty => new SKColor(0u); } public class SKColorSpace : SKObject, ISKNonVirtualReferenceCounted, ISKReferenceCounted { private sealed class SKColorSpaceStatic : SKColorSpace { internal SKColorSpaceStatic(IntPtr x) : base(x, owns: false) { } protected override void Dispose(bool disposing) { } } private static readonly SKColorSpace srgb; private static readonly SKColorSpace srgbLinear; public bool GammaIsCloseToSrgb => SkiaApi.sk_colorspace_gamma_close_to_srgb(Handle); public bool GammaIsLinear => SkiaApi.sk_colorspace_gamma_is_linear(Handle); public bool IsSrgb => SkiaApi.sk_colorspace_is_srgb(Handle); [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public SKColorSpaceType Type => SKColorSpaceType.Rgb; [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetNumericalTransferFunction() instead.")] public SKNamedGamma NamedGamma { get { SKColorSpaceTransferFn numericalTransferFunction = GetNumericalTransferFunction(); SKColorSpaceTransferFn sKColorSpaceTransferFn = numericalTransferFunction; if (numericalTransferFunction == SKColorSpaceTransferFn.Empty) { return SKNamedGamma.NonStandard; } if (numericalTransferFunction == SKColorSpaceTransferFn.Linear) { return SKNamedGamma.Linear; } if (numericalTransferFunction == SKColorSpaceTransferFn.Srgb) { return SKNamedGamma.Srgb; } if (numericalTransferFunction == SKColorSpaceTransferFn.TwoDotTwo) { return SKNamedGamma.TwoDotTwoCurve; } return SKNamedGamma.NonStandard; } } public bool IsNumericalTransferFunction { get { SKColorSpaceTransferFn fn; return GetNumericalTransferFunction(out fn); } } static SKColorSpace() { srgb = new SKColorSpaceStatic(SkiaApi.sk_colorspace_new_srgb()); srgbLinear = new SKColorSpaceStatic(SkiaApi.sk_colorspace_new_srgb_linear()); } internal static void EnsureStaticInstanceAreInitialized() { } internal SKColorSpace(IntPtr handle, bool owns) : base(handle, owns) { } void ISKNonVirtualReferenceCounted.ReferenceNative() { SkiaApi.sk_colorspace_ref(Handle); } void ISKNonVirtualReferenceCounted.UnreferenceNative() { SkiaApi.sk_colorspace_unref(Handle); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public static bool Equal(SKColorSpace left, SKColorSpace right) { if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } return SkiaApi.sk_colorspace_equals(left.Handle, right.Handle); } public static SKColorSpace CreateSrgb() { return srgb; } public static SKColorSpace CreateSrgbLinear() { return srgbLinear; } public static SKColorSpace CreateIcc(IntPtr input, long length) { return CreateIcc(SKColorSpaceIccProfile.Create(input, length)); } public unsafe static SKColorSpace CreateIcc(byte[] input, long length) { if (input == null) { throw new ArgumentNullException("input"); } fixed (byte* ptr = input) { return CreateIcc(SKColorSpaceIccProfile.Create((IntPtr)ptr, length)); } } public static SKColorSpace CreateIcc(byte[] input) { return CreateIcc(input.AsSpan()); } public static SKColorSpace CreateIcc(ReadOnlySpan input) { return CreateIcc(SKColorSpaceIccProfile.Create(input)); } public static SKColorSpace CreateIcc(SKData input) { return CreateIcc(SKColorSpaceIccProfile.Create(input)); } public static SKColorSpace CreateIcc(SKColorSpaceIccProfile profile) { if (profile == null) { throw new ArgumentNullException("profile"); } return SKObject.Referenced(GetObject(SkiaApi.sk_colorspace_new_icc(profile.Handle)), profile); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKColorSpaceRenderTargetGamma gamma, SKMatrix44 toXyzD50, SKColorSpaceFlags flags) { return CreateRgb(gamma, toXyzD50); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKColorSpaceRenderTargetGamma gamma, SKColorSpaceGamut gamut, SKColorSpaceFlags flags) { return CreateRgb(gamma, gamut); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKColorSpaceTransferFn coeffs, SKMatrix44 toXyzD50, SKColorSpaceFlags flags) { return CreateRgb(coeffs, toXyzD50); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKColorSpaceTransferFn coeffs, SKColorSpaceGamut gamut, SKColorSpaceFlags flags) { return CreateRgb(coeffs, gamut); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKColorSpaceRenderTargetGamma gamma, SKMatrix44 toXyzD50) { if (toXyzD50 == null) { throw new ArgumentNullException("toXyzD50"); } return CreateRgb(gamma.ToColorSpaceTransferFn(), toXyzD50.ToColorSpaceXyz()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKColorSpaceRenderTargetGamma gamma, SKColorSpaceGamut gamut) { return CreateRgb(gamma.ToColorSpaceTransferFn(), gamut.ToColorSpaceXyz()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKColorSpaceTransferFn coeffs, SKMatrix44 toXyzD50) { if (toXyzD50 == null) { throw new ArgumentNullException("toXyzD50"); } return CreateRgb(coeffs, toXyzD50.ToColorSpaceXyz()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKColorSpaceTransferFn coeffs, SKColorSpaceGamut gamut) { return CreateRgb(coeffs, gamut.ToColorSpaceXyz()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKNamedGamma gamma, SKMatrix44 toXyzD50) { if (toXyzD50 == null) { throw new ArgumentNullException("toXyzD50"); } return CreateRgb(gamma.ToColorSpaceTransferFn(), toXyzD50.ToColorSpaceXyz()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRgb(SKColorSpaceTransferFn, SKColorSpaceXyz) instead.")] public static SKColorSpace CreateRgb(SKNamedGamma gamma, SKColorSpaceGamut gamut) { return CreateRgb(gamma.ToColorSpaceTransferFn(), gamut.ToColorSpaceXyz()); } public unsafe static SKColorSpace CreateRgb(SKColorSpaceTransferFn transferFn, SKColorSpaceXyz toXyzD50) { return GetObject(SkiaApi.sk_colorspace_new_rgb(&transferFn, &toXyzD50)); } public SKColorSpaceTransferFn GetNumericalTransferFunction() { if (!GetNumericalTransferFunction(out var fn)) { return SKColorSpaceTransferFn.Empty; } return fn; } public unsafe bool GetNumericalTransferFunction(out SKColorSpaceTransferFn fn) { fixed (SKColorSpaceTransferFn* transferFn = &fn) { return SkiaApi.sk_colorspace_is_numerical_transfer_fn(Handle, transferFn); } } public SKColorSpaceIccProfile ToProfile() { SKColorSpaceIccProfile sKColorSpaceIccProfile = new SKColorSpaceIccProfile(); SkiaApi.sk_colorspace_to_profile(Handle, sKColorSpaceIccProfile.Handle); return sKColorSpaceIccProfile; } public unsafe bool ToColorSpaceXyz(out SKColorSpaceXyz toXyzD50) { fixed (SKColorSpaceXyz* toXYZD = &toXyzD50) { return SkiaApi.sk_colorspace_to_xyzd50(Handle, toXYZD); } } public SKColorSpaceXyz ToColorSpaceXyz() { if (!ToColorSpaceXyz(out var toXyzD)) { return SKColorSpaceXyz.Empty; } return toXyzD; } public SKColorSpace ToLinearGamma() { return GetObject(SkiaApi.sk_colorspace_make_linear_gamma(Handle)); } public SKColorSpace ToSrgbGamma() { return GetObject(SkiaApi.sk_colorspace_make_srgb_gamma(Handle)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ToColorSpaceXyz() instead.")] public SKMatrix44 ToXyzD50() { return ToColorSpaceXyz().ToMatrix44(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ToColorSpaceXyz(out SKColorSpaceXyz) instead.")] public bool ToXyzD50(SKMatrix44 toXyzD50) { if (toXyzD50 == null) { throw new ArgumentNullException("toXyzD50"); } if (ToColorSpaceXyz(out var toXyzD51)) { SKMatrix44 sKMatrix = toXyzD51.ToMatrix44(); if (sKMatrix != null) { toXyzD50.SetColumnMajor(sKMatrix.ToColumnMajor()); return true; } } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public SKMatrix44 FromXyzD50() { return ToXyzD50()?.Invert(); } internal static SKColorSpace GetObject(IntPtr handle, bool owns = true, bool unrefExisting = true) { return SKObject.GetOrAddObject(handle, owns, unrefExisting, (IntPtr h, bool o) => new SKColorSpace(h, o)); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKColorSpaceTransferFn instead.")] public enum SKColorSpaceRenderTargetGamma { Linear, Srgb } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKColorSpaceXyz instead.")] public enum SKColorSpaceGamut { AdobeRgb = 1, Dcip3D65 = 2, Rec2020 = 3, Srgb = 0 } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public enum SKColorSpaceType { Cmyk = 1, Gray = 2, Rgb = 0 } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKColorSpaceTransferFn instead.")] public enum SKNamedGamma { Linear, Srgb, TwoDotTwoCurve, NonStandard } public struct SKColorSpacePrimaries : IEquatable { public static readonly SKColorSpacePrimaries Empty; private float fRX; private float fRY; private float fGX; private float fGY; private float fBX; private float fBY; private float fWX; private float fWY; public readonly float[] Values => new float[8] { fRX, fRY, fGX, fGY, fBX, fBY, fWX, fWY }; public float RX { readonly get { return fRX; } set { fRX = value; } } public float RY { readonly get { return fRY; } set { fRY = value; } } public float GX { readonly get { return fGX; } set { fGX = value; } } public float GY { readonly get { return fGY; } set { fGY = value; } } public float BX { readonly get { return fBX; } set { fBX = value; } } public float BY { readonly get { return fBY; } set { fBY = value; } } public float WX { readonly get { return fWX; } set { fWX = value; } } public float WY { readonly get { return fWY; } set { fWY = value; } } public SKColorSpacePrimaries(float[] values) { if (values == null) { throw new ArgumentNullException("values"); } if (values.Length != 8) { throw new ArgumentException("The values must have exactly 8 items, one for each of [RX, RY, GX, GY, BX, BY, WX, WY].", "values"); } fRX = values[0]; fRY = values[1]; fGX = values[2]; fGY = values[3]; fBX = values[4]; fBY = values[5]; fWX = values[6]; fWY = values[7]; } public SKColorSpacePrimaries(float rx, float ry, float gx, float gy, float bx, float by, float wx, float wy) { fRX = rx; fRY = ry; fGX = gx; fGY = gy; fBX = bx; fBY = by; fWX = wx; fWY = wy; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ToColorSpaceXyz() instead.")] public readonly SKMatrix44 ToXyzD50() { return ToMatrix44(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ToColorSpaceXyz(out SKColorSpaceXyz) instead.")] public readonly bool ToXyzD50(SKMatrix44 toXyzD50) { if (toXyzD50 == null) { throw new ArgumentNullException("toXyzD50"); } SKMatrix44 sKMatrix = ToMatrix44(); if (sKMatrix != null) { toXyzD50.SetColumnMajor(sKMatrix.ToColumnMajor()); } return sKMatrix != null; } internal readonly SKMatrix44 ToMatrix44() { if (!ToMatrix44(out var toXyzD)) { return null; } return toXyzD; } internal readonly bool ToMatrix44(out SKMatrix44 toXyzD50) { if (!ToColorSpaceXyz(out var toXyzD51)) { toXyzD50 = null; return false; } toXyzD50 = toXyzD51.ToMatrix44(); return true; } public unsafe readonly bool ToColorSpaceXyz(out SKColorSpaceXyz toXyzD50) { fixed (SKColorSpacePrimaries* primaries = &this) { fixed (SKColorSpaceXyz* toXYZD = &toXyzD50) { return SkiaApi.sk_colorspace_primaries_to_xyzd50(primaries, toXYZD); } } } public readonly SKColorSpaceXyz ToColorSpaceXyz() { if (!ToColorSpaceXyz(out var toXyzD)) { return SKColorSpaceXyz.Empty; } return toXyzD; } public readonly bool Equals(SKColorSpacePrimaries obj) { if (fRX == obj.fRX && fRY == obj.fRY && fGX == obj.fGX && fGY == obj.fGY && fBX == obj.fBX && fBY == obj.fBY && fWX == obj.fWX) { return fWY == obj.fWY; } return false; } public override readonly bool Equals(object obj) { if (obj is SKColorSpacePrimaries obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKColorSpacePrimaries left, SKColorSpacePrimaries right) { return left.Equals(right); } public static bool operator !=(SKColorSpacePrimaries left, SKColorSpacePrimaries right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fRX); hashCode.Add(fRY); hashCode.Add(fGX); hashCode.Add(fGY); hashCode.Add(fBX); hashCode.Add(fBY); hashCode.Add(fWX); hashCode.Add(fWY); return hashCode.ToHashCode(); } } public struct SKColorSpaceTransferFn : IEquatable { public static readonly SKColorSpaceTransferFn Empty; private float fG; private float fA; private float fB; private float fC; private float fD; private float fE; private float fF; public unsafe static SKColorSpaceTransferFn Srgb { get { SKColorSpaceTransferFn result = default(SKColorSpaceTransferFn); SkiaApi.sk_colorspace_transfer_fn_named_srgb(&result); return result; } } public unsafe static SKColorSpaceTransferFn TwoDotTwo { get { SKColorSpaceTransferFn result = default(SKColorSpaceTransferFn); SkiaApi.sk_colorspace_transfer_fn_named_2dot2(&result); return result; } } public unsafe static SKColorSpaceTransferFn Linear { get { SKColorSpaceTransferFn result = default(SKColorSpaceTransferFn); SkiaApi.sk_colorspace_transfer_fn_named_linear(&result); return result; } } public unsafe static SKColorSpaceTransferFn Rec2020 { get { SKColorSpaceTransferFn result = default(SKColorSpaceTransferFn); SkiaApi.sk_colorspace_transfer_fn_named_rec2020(&result); return result; } } public unsafe static SKColorSpaceTransferFn Pq { get { SKColorSpaceTransferFn result = default(SKColorSpaceTransferFn); SkiaApi.sk_colorspace_transfer_fn_named_pq(&result); return result; } } public unsafe static SKColorSpaceTransferFn Hlg { get { SKColorSpaceTransferFn result = default(SKColorSpaceTransferFn); SkiaApi.sk_colorspace_transfer_fn_named_hlg(&result); return result; } } public readonly float[] Values => new float[7] { fG, fA, fB, fC, fD, fE, fF }; public float G { readonly get { return fG; } set { fG = value; } } public float A { readonly get { return fA; } set { fA = value; } } public float B { readonly get { return fB; } set { fB = value; } } public float C { readonly get { return fC; } set { fC = value; } } public float D { readonly get { return fD; } set { fD = value; } } public float E { readonly get { return fE; } set { fE = value; } } public float F { readonly get { return fF; } set { fF = value; } } public SKColorSpaceTransferFn(float[] values) { if (values == null) { throw new ArgumentNullException("values"); } if (values.Length != 7) { throw new ArgumentException("The values must have exactly 7 items, one for each of [G, A, B, C, D, E, F].", "values"); } fG = values[0]; fA = values[1]; fB = values[2]; fC = values[3]; fD = values[4]; fE = values[5]; fF = values[6]; } public SKColorSpaceTransferFn(float g, float a, float b, float c, float d, float e, float f) { fG = g; fA = a; fB = b; fC = c; fD = d; fE = e; fF = f; } public unsafe readonly SKColorSpaceTransferFn Invert() { SKColorSpaceTransferFn result = default(SKColorSpaceTransferFn); fixed (SKColorSpaceTransferFn* src = &this) { SkiaApi.sk_colorspace_transfer_fn_invert(src, &result); } return result; } public unsafe readonly float Transform(float x) { fixed (SKColorSpaceTransferFn* transferFn = &this) { return SkiaApi.sk_colorspace_transfer_fn_eval(transferFn, x); } } public readonly bool Equals(SKColorSpaceTransferFn obj) { if (fG == obj.fG && fA == obj.fA && fB == obj.fB && fC == obj.fC && fD == obj.fD && fE == obj.fE) { return fF == obj.fF; } return false; } public override readonly bool Equals(object obj) { if (obj is SKColorSpaceTransferFn obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKColorSpaceTransferFn left, SKColorSpaceTransferFn right) { return left.Equals(right); } public static bool operator !=(SKColorSpaceTransferFn left, SKColorSpaceTransferFn right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fG); hashCode.Add(fA); hashCode.Add(fB); hashCode.Add(fC); hashCode.Add(fD); hashCode.Add(fE); hashCode.Add(fF); return hashCode.ToHashCode(); } } public struct SKColorSpaceXyz : IEquatable { public static readonly SKColorSpaceXyz Empty; private float fM00; private float fM01; private float fM02; private float fM10; private float fM11; private float fM12; private float fM20; private float fM21; private float fM22; public unsafe static SKColorSpaceXyz Srgb { get { SKColorSpaceXyz result = default(SKColorSpaceXyz); SkiaApi.sk_colorspace_xyz_named_srgb(&result); return result; } } public unsafe static SKColorSpaceXyz AdobeRgb { get { SKColorSpaceXyz result = default(SKColorSpaceXyz); SkiaApi.sk_colorspace_xyz_named_adobe_rgb(&result); return result; } } [Obsolete("Use DisplayP3 instead.")] public static SKColorSpaceXyz Dcip3 => DisplayP3; public unsafe static SKColorSpaceXyz DisplayP3 { get { SKColorSpaceXyz result = default(SKColorSpaceXyz); SkiaApi.sk_colorspace_xyz_named_display_p3(&result); return result; } } public unsafe static SKColorSpaceXyz Rec2020 { get { SKColorSpaceXyz result = default(SKColorSpaceXyz); SkiaApi.sk_colorspace_xyz_named_rec2020(&result); return result; } } public unsafe static SKColorSpaceXyz Xyz { get { SKColorSpaceXyz result = default(SKColorSpaceXyz); SkiaApi.sk_colorspace_xyz_named_xyz(&result); return result; } } public float[] Values { readonly get { return new float[9] { fM00, fM01, fM02, fM10, fM11, fM12, fM20, fM21, fM22 }; } set { if (value.Length != 9) { throw new ArgumentException("The matrix array must have a length of 9.", "value"); } fM00 = value[0]; fM01 = value[1]; fM02 = value[2]; fM10 = value[3]; fM11 = value[4]; fM12 = value[5]; fM20 = value[6]; fM21 = value[7]; fM22 = value[8]; } } public readonly float this[int x, int y] { get { if (x < 0 || x >= 3) { throw new ArgumentOutOfRangeException("x"); } if (y < 0 || y >= 3) { throw new ArgumentOutOfRangeException("y"); } return (x + y * 3) switch { 0 => fM00, 1 => fM01, 2 => fM02, 3 => fM10, 4 => fM11, 5 => fM12, 6 => fM20, 7 => fM21, 8 => fM22, _ => throw new ArgumentOutOfRangeException("index"), }; } } public SKColorSpaceXyz(float value) { fM00 = value; fM01 = value; fM02 = value; fM10 = value; fM11 = value; fM12 = value; fM20 = value; fM21 = value; fM22 = value; } public SKColorSpaceXyz(float[] values) { if (values == null) { throw new ArgumentNullException("values"); } if (values.Length != 9) { throw new ArgumentException("The matrix array must have a length of 9.", "values"); } fM00 = values[0]; fM01 = values[1]; fM02 = values[2]; fM10 = values[3]; fM11 = values[4]; fM12 = values[5]; fM20 = values[6]; fM21 = values[7]; fM22 = values[8]; } public SKColorSpaceXyz(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) { fM00 = m00; fM01 = m01; fM02 = m02; fM10 = m10; fM11 = m11; fM12 = m12; fM20 = m20; fM21 = m21; fM22 = m22; } public unsafe readonly SKColorSpaceXyz Invert() { SKColorSpaceXyz result = default(SKColorSpaceXyz); fixed (SKColorSpaceXyz* src = &this) { SkiaApi.sk_colorspace_xyz_invert(src, &result); } return result; } public unsafe static SKColorSpaceXyz Concat(SKColorSpaceXyz a, SKColorSpaceXyz b) { SKColorSpaceXyz result = default(SKColorSpaceXyz); SkiaApi.sk_colorspace_xyz_concat(&a, &b, &result); return result; } internal readonly SKMatrix44 ToMatrix44() { SKMatrix44 sKMatrix = new SKMatrix44(); sKMatrix.Set3x3RowMajor(Values); return sKMatrix; } public readonly bool Equals(SKColorSpaceXyz obj) { if (fM00 == obj.fM00 && fM01 == obj.fM01 && fM02 == obj.fM02 && fM10 == obj.fM10 && fM11 == obj.fM11 && fM12 == obj.fM12 && fM20 == obj.fM20 && fM21 == obj.fM21) { return fM22 == obj.fM22; } return false; } public override readonly bool Equals(object obj) { if (obj is SKColorSpaceXyz obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKColorSpaceXyz left, SKColorSpaceXyz right) { return left.Equals(right); } public static bool operator !=(SKColorSpaceXyz left, SKColorSpaceXyz right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fM00); hashCode.Add(fM01); hashCode.Add(fM02); hashCode.Add(fM10); hashCode.Add(fM11); hashCode.Add(fM12); hashCode.Add(fM20); hashCode.Add(fM21); hashCode.Add(fM22); return hashCode.ToHashCode(); } } public class SKColorSpaceIccProfile : SKObject { public unsafe long Size { get { uint num = default(uint); SkiaApi.sk_colorspace_icc_profile_get_buffer(Handle, &num); return num; } } public unsafe IntPtr Buffer => (IntPtr)SkiaApi.sk_colorspace_icc_profile_get_buffer(Handle, null); internal SKColorSpaceIccProfile(IntPtr handle, bool owns) : base(handle, owns) { } public SKColorSpaceIccProfile() : this(SkiaApi.sk_colorspace_icc_profile_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKColorSpaceIccProfile instance."); } } protected override void DisposeNative() { SkiaApi.sk_colorspace_icc_profile_delete(Handle); } public unsafe bool ToColorSpaceXyz(out SKColorSpaceXyz toXyzD50) { fixed (SKColorSpaceXyz* toXYZD = &toXyzD50) { return SkiaApi.sk_colorspace_icc_profile_get_to_xyzd50(Handle, toXYZD); } } public SKColorSpaceXyz ToColorSpaceXyz() { if (!ToColorSpaceXyz(out var toXyzD)) { return SKColorSpaceXyz.Empty; } return toXyzD; } public static SKColorSpaceIccProfile Create(byte[] data) { return Create(data.AsSpan()); } public static SKColorSpaceIccProfile Create(ReadOnlySpan data) { if (data.IsEmpty) { return null; } SKData sKData = SKData.CreateCopy(data); SKColorSpaceIccProfile sKColorSpaceIccProfile = Create(sKData); if (sKColorSpaceIccProfile == null) { sKData.Dispose(); } return sKColorSpaceIccProfile; } public static SKColorSpaceIccProfile Create(SKData data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.IsEmpty) { return null; } return SKObject.Referenced(Create(data.Data, data.Size), data); } public unsafe static SKColorSpaceIccProfile Create(IntPtr data, long length) { if (data == IntPtr.Zero) { throw new ArgumentNullException("data"); } if (length <= 0) { return null; } SKColorSpaceIccProfile sKColorSpaceIccProfile = new SKColorSpaceIccProfile(); if (!SkiaApi.sk_colorspace_icc_profile_parse((void*)data, (IntPtr)length, sKColorSpaceIccProfile.Handle)) { sKColorSpaceIccProfile.Dispose(); sKColorSpaceIccProfile = null; } return sKColorSpaceIccProfile; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported.")] public class SKColorTable : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration { public const int MaxLength = 256; public int Count => SkiaApi.sk_colortable_count(Handle); public SKPMColor[] Colors { get { int count = Count; IntPtr intPtr = ReadColors(); if (count == 0 || intPtr == IntPtr.Zero) { return new SKPMColor[0]; } return SKObject.PtrToStructureArray(intPtr, count); } } public SKColor[] UnPreMultipledColors => SKPMColor.UnPreMultiply(Colors); public SKPMColor this[int index] { get { int count = Count; IntPtr intPtr = ReadColors(); if (index < 0 || index >= count || intPtr == IntPtr.Zero) { throw new ArgumentOutOfRangeException("index"); } return SKObject.PtrToStructure(intPtr, index); } } internal SKColorTable(IntPtr x, bool owns) : base(x, owns) { } public SKColorTable() : this(new SKPMColor[256]) { } public SKColorTable(int count) : this(new SKPMColor[count]) { } public SKColorTable(SKColor[] colors) : this(colors, colors.Length) { } public SKColorTable(SKColor[] colors, int count) : this(SKPMColor.PreMultiply(colors), count) { } public SKColorTable(SKPMColor[] colors) : this(colors, colors.Length) { } public SKColorTable(SKPMColor[] colors, int count) : this(CreateNew(colors, count), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKColorTable instance."); } } private unsafe static IntPtr CreateNew(SKPMColor[] colors, int count) { fixed (SKPMColor* colors2 = colors) { return SkiaApi.sk_colortable_new((uint*)colors2, count); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public SKColor GetUnPreMultipliedColor(int index) { return SKPMColor.UnPreMultiply(this[index]); } public unsafe IntPtr ReadColors() { uint* ptr = default(uint*); SkiaApi.sk_colortable_read_colors(Handle, &ptr); return (IntPtr)ptr; } } public class SKData : SKObject, ISKNonVirtualReferenceCounted, ISKReferenceCounted { private class SKDataStream : UnmanagedMemoryStream { private SKData host; private readonly bool disposeHost; public unsafe SKDataStream(SKData host, bool disposeHost = false) : base((byte*)(void*)host.Data, host.Size, host.Size, FileAccess.ReadWrite) { this.host = host; this.disposeHost = disposeHost; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposeHost) { host?.Dispose(); } host = null; } } private sealed class SKDataStatic : SKData { internal SKDataStatic(IntPtr x) : base(x, owns: false) { } protected override void Dispose(bool disposing) { } } internal const int CopyBufferSize = 81920; private static readonly SKData empty; public static SKData Empty => empty; public bool IsEmpty => Size == 0; public long Size => (long)SkiaApi.sk_data_get_size(Handle); public unsafe IntPtr Data => (IntPtr)SkiaApi.sk_data_get_data(Handle); public unsafe Span Span => new Span((void*)Data, (int)Size); static SKData() { empty = new SKDataStatic(SkiaApi.sk_data_new_empty()); } internal static void EnsureStaticInstanceAreInitialized() { } internal SKData(IntPtr x, bool owns) : base(x, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } void ISKNonVirtualReferenceCounted.ReferenceNative() { SkiaApi.sk_data_ref(Handle); } void ISKNonVirtualReferenceCounted.UnreferenceNative() { SkiaApi.sk_data_unref(Handle); } public static SKData CreateCopy(IntPtr bytes, int length) { return CreateCopy(bytes, (ulong)length); } public static SKData CreateCopy(IntPtr bytes, long length) { return CreateCopy(bytes, (ulong)length); } public unsafe static SKData CreateCopy(IntPtr bytes, ulong length) { if (!PlatformConfiguration.Is64Bit && length > uint.MaxValue) { throw new ArgumentOutOfRangeException("length", "The length exceeds the size of pointers."); } return GetObject(SkiaApi.sk_data_new_with_copy((void*)bytes, (IntPtr)(long)length)); } public static SKData CreateCopy(byte[] bytes) { return CreateCopy(bytes, (ulong)bytes.Length); } public unsafe static SKData CreateCopy(byte[] bytes, ulong length) { fixed (byte* src = bytes) { return GetObject(SkiaApi.sk_data_new_with_copy(src, (IntPtr)(long)length)); } } public unsafe static SKData CreateCopy(ReadOnlySpan bytes) { fixed (byte* ptr = bytes) { return CreateCopy((IntPtr)ptr, (ulong)bytes.Length); } } public static SKData Create(int size) { return GetObject(SkiaApi.sk_data_new_uninitialized((IntPtr)size)); } public static SKData Create(long size) { return GetObject(SkiaApi.sk_data_new_uninitialized((IntPtr)size)); } public static SKData Create(ulong size) { if (!PlatformConfiguration.Is64Bit && size > uint.MaxValue) { throw new ArgumentOutOfRangeException("size", "The size exceeds the size of pointers."); } return GetObject(SkiaApi.sk_data_new_uninitialized((IntPtr)(long)size)); } public unsafe static SKData Create(string filename) { if (string.IsNullOrEmpty(filename)) { throw new ArgumentException("The filename cannot be empty.", "filename"); } fixed (byte* encodedText = StringUtilities.GetEncodedText(filename, SKTextEncoding.Utf8, addNull: true)) { return GetObject(SkiaApi.sk_data_new_from_file(encodedText)); } } public static SKData Create(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } if (stream.CanSeek) { return Create(stream, stream.Length - stream.Position); } using SKDynamicMemoryWStream sKDynamicMemoryWStream = new SKDynamicMemoryWStream(); using (SKManagedStream sKManagedStream = new SKManagedStream(stream)) { sKManagedStream.CopyTo(sKDynamicMemoryWStream); } return sKDynamicMemoryWStream.DetachAsData(); } public static SKData Create(Stream stream, int length) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKManagedStream stream2 = new SKManagedStream(stream); return Create(stream2, length); } public static SKData Create(Stream stream, ulong length) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKManagedStream stream2 = new SKManagedStream(stream); return Create(stream2, length); } public static SKData Create(Stream stream, long length) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKManagedStream stream2 = new SKManagedStream(stream); return Create(stream2, length); } public static SKData Create(SKStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } return Create(stream, stream.Length); } public static SKData Create(SKStream stream, int length) { if (stream == null) { throw new ArgumentNullException("stream"); } return GetObject(SkiaApi.sk_data_new_from_stream(stream.Handle, (IntPtr)length)); } public static SKData Create(SKStream stream, ulong length) { if (stream == null) { throw new ArgumentNullException("stream"); } return GetObject(SkiaApi.sk_data_new_from_stream(stream.Handle, (IntPtr)(long)length)); } public static SKData Create(SKStream stream, long length) { if (stream == null) { throw new ArgumentNullException("stream"); } return GetObject(SkiaApi.sk_data_new_from_stream(stream.Handle, (IntPtr)length)); } public static SKData Create(IntPtr address, int length) { return Create(address, length, null, null); } public static SKData Create(IntPtr address, int length, SKDataReleaseDelegate releaseProc) { return Create(address, length, releaseProc, null); } public unsafe static SKData Create(IntPtr address, int length, SKDataReleaseDelegate releaseProc, object context) { SKDataReleaseDelegate managedDel = ((releaseProc != null && context != null) ? ((SKDataReleaseDelegate)delegate(IntPtr addr, object _) { releaseProc(addr, context); }) : releaseProc); GCHandle gch; IntPtr contextPtr; SKDataReleaseProxyDelegate proc = DelegateProxies.Create(managedDel, DelegateProxies.SKDataReleaseDelegateProxy, out gch, out contextPtr); return GetObject(SkiaApi.sk_data_new_with_proc((void*)address, (IntPtr)length, proc, (void*)contextPtr)); } internal static SKData FromCString(string str) { byte[] bytes = Encoding.ASCII.GetBytes(str ?? string.Empty); return CreateCopy(bytes, (ulong)(bytes.Length + 1)); } public SKData Subset(ulong offset, ulong length) { if (!PlatformConfiguration.Is64Bit) { if (length > uint.MaxValue) { throw new ArgumentOutOfRangeException("length", "The length exceeds the size of pointers."); } if (offset > uint.MaxValue) { throw new ArgumentOutOfRangeException("offset", "The offset exceeds the size of pointers."); } } return GetObject(SkiaApi.sk_data_new_subset(Handle, (IntPtr)(long)offset, (IntPtr)(long)length)); } public byte[] ToArray() { byte[] result = AsSpan().ToArray(); GC.KeepAlive(this); return result; } public Stream AsStream() { return new SKDataStream(this); } public Stream AsStream(bool streamDisposesData) { return new SKDataStream(this, streamDisposesData); } public unsafe ReadOnlySpan AsSpan() { return new ReadOnlySpan((void*)Data, (int)Size); } public void SaveTo(Stream target) { if (target == null) { throw new ArgumentNullException("target"); } IntPtr data = Data; long size = Size; Utils.RentedArray rentedArray = Utils.RentArray(81920); try { long num = size; while (num > 0) { int num2 = (int)Math.Min(81920L, num); Marshal.Copy(data, (byte[])rentedArray, 0, num2); num -= num2; data += num2; target.Write((byte[])rentedArray, 0, num2); } GC.KeepAlive(this); } finally { rentedArray.Dispose(); } } internal static SKData GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKData(h, o)); } } public class SKDocument : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration { public const float DefaultRasterDpi = 72f; internal SKDocument(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public void Abort() { SkiaApi.sk_document_abort(Handle); } public unsafe SKCanvas BeginPage(float width, float height) { return SKObject.OwnedBy(SKCanvas.GetObject(SkiaApi.sk_document_begin_page(Handle, width, height, null), owns: false), this); } public unsafe SKCanvas BeginPage(float width, float height, SKRect content) { return SKObject.OwnedBy(SKCanvas.GetObject(SkiaApi.sk_document_begin_page(Handle, width, height, &content), owns: false), this); } public void EndPage() { SkiaApi.sk_document_end_page(Handle); } public void Close() { SkiaApi.sk_document_close(Handle); } public static SKDocument CreateXps(string path) { return CreateXps(path, 72f); } public static SKDocument CreateXps(Stream stream) { return CreateXps(stream, 72f); } public static SKDocument CreateXps(SKWStream stream) { return CreateXps(stream, 72f); } public static SKDocument CreateXps(string path, float dpi) { if (path == null) { throw new ArgumentNullException("path"); } SKWStream sKWStream = SKFileWStream.OpenStream(path); return SKObject.Owned(CreateXps(sKWStream, dpi), sKWStream); } public static SKDocument CreateXps(Stream stream, float dpi) { if (stream == null) { throw new ArgumentNullException("stream"); } SKManagedWStream sKManagedWStream = new SKManagedWStream(stream); return SKObject.Owned(CreateXps(sKManagedWStream, dpi), sKManagedWStream); } public static SKDocument CreateXps(SKWStream stream, float dpi) { if (stream == null) { throw new ArgumentNullException("stream"); } return SKObject.Referenced(GetObject(SkiaApi.sk_document_create_xps_from_stream(stream.Handle, dpi)), stream); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreatePdf(SKWStream, SKDocumentPdfMetadata) instead.")] public static SKDocument CreatePdf(SKWStream stream, SKDocumentPdfMetadata metadata, float dpi) { metadata.RasterDpi = dpi; return CreatePdf(stream, metadata); } public static SKDocument CreatePdf(string path) { if (path == null) { throw new ArgumentNullException("path"); } SKWStream sKWStream = SKFileWStream.OpenStream(path); return SKObject.Owned(CreatePdf(sKWStream), sKWStream); } public static SKDocument CreatePdf(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } SKManagedWStream sKManagedWStream = new SKManagedWStream(stream); return SKObject.Owned(CreatePdf(sKManagedWStream), sKManagedWStream); } public static SKDocument CreatePdf(SKWStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } return SKObject.Referenced(GetObject(SkiaApi.sk_document_create_pdf_from_stream(stream.Handle)), stream); } public static SKDocument CreatePdf(string path, float dpi) { return CreatePdf(path, new SKDocumentPdfMetadata(dpi)); } public static SKDocument CreatePdf(Stream stream, float dpi) { return CreatePdf(stream, new SKDocumentPdfMetadata(dpi)); } public static SKDocument CreatePdf(SKWStream stream, float dpi) { return CreatePdf(stream, new SKDocumentPdfMetadata(dpi)); } public static SKDocument CreatePdf(string path, SKDocumentPdfMetadata metadata) { if (path == null) { throw new ArgumentNullException("path"); } SKWStream sKWStream = SKFileWStream.OpenStream(path); return SKObject.Owned(CreatePdf(sKWStream, metadata), sKWStream); } public static SKDocument CreatePdf(Stream stream, SKDocumentPdfMetadata metadata) { if (stream == null) { throw new ArgumentNullException("stream"); } SKManagedWStream sKManagedWStream = new SKManagedWStream(stream); return SKObject.Owned(CreatePdf(sKManagedWStream, metadata), sKManagedWStream); } public unsafe static SKDocument CreatePdf(SKWStream stream, SKDocumentPdfMetadata metadata) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKString sKString = SKString.Create(metadata.Title); using SKString sKString2 = SKString.Create(metadata.Author); using SKString sKString3 = SKString.Create(metadata.Subject); using SKString sKString4 = SKString.Create(metadata.Keywords); using SKString sKString5 = SKString.Create(metadata.Creator); using SKString sKString6 = SKString.Create(metadata.Producer); SKDocumentPdfMetadataInternal sKDocumentPdfMetadataInternal = new SKDocumentPdfMetadataInternal { fTitle = (sKString?.Handle ?? IntPtr.Zero), fAuthor = (sKString2?.Handle ?? IntPtr.Zero), fSubject = (sKString3?.Handle ?? IntPtr.Zero), fKeywords = (sKString4?.Handle ?? IntPtr.Zero), fCreator = (sKString5?.Handle ?? IntPtr.Zero), fProducer = (sKString6?.Handle ?? IntPtr.Zero), fRasterDPI = metadata.RasterDpi, fPDFA = (metadata.PdfA ? ((byte)1) : ((byte)0)), fEncodingQuality = metadata.EncodingQuality }; if (metadata.Creation.HasValue) { SKTimeDateTimeInternal sKTimeDateTimeInternal = SKTimeDateTimeInternal.Create(metadata.Creation.Value); sKDocumentPdfMetadataInternal.fCreation = &sKTimeDateTimeInternal; } if (metadata.Modified.HasValue) { SKTimeDateTimeInternal sKTimeDateTimeInternal2 = SKTimeDateTimeInternal.Create(metadata.Modified.Value); sKDocumentPdfMetadataInternal.fModified = &sKTimeDateTimeInternal2; } return SKObject.Referenced(GetObject(SkiaApi.sk_document_create_pdf_from_stream_with_metadata(stream.Handle, &sKDocumentPdfMetadataInternal)), stream); } internal static SKDocument GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new SKDocument(handle, owns: true); } return null; } } public class SKDrawable : SKObject, ISKReferenceCounted { private static readonly SKManagedDrawableDelegates delegates; private int fromNative; public uint GenerationId => SkiaApi.sk_drawable_get_generation_id(Handle); public unsafe SKRect Bounds { get { SKRect result = default(SKRect); SkiaApi.sk_drawable_get_bounds(Handle, &result); return result; } } unsafe static SKDrawable() { delegates = new SKManagedDrawableDelegates { fDraw = DrawInternal, fGetBounds = GetBoundsInternal, fNewPictureSnapshot = NewPictureSnapshotInternal, fDestroy = DestroyInternal }; SkiaApi.sk_manageddrawable_set_procs(delegates); } protected SKDrawable() : this(owns: true) { } protected unsafe SKDrawable(bool owns) : base(IntPtr.Zero, owns) { IntPtr intPtr = DelegateProxies.CreateUserData(this, makeWeak: true); Handle = SkiaApi.sk_manageddrawable_new((void*)intPtr); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKDrawable instance."); } } internal SKDrawable(IntPtr x, bool owns) : base(x, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { if (Interlocked.CompareExchange(ref fromNative, 0, 0) == 0) { SkiaApi.sk_drawable_unref(Handle); } } public unsafe void Draw(SKCanvas canvas, ref SKMatrix matrix) { fixed (SKMatrix* param = &matrix) { SkiaApi.sk_drawable_draw(Handle, canvas.Handle, param); } } public void Draw(SKCanvas canvas, float x, float y) { SKMatrix matrix = SKMatrix.CreateTranslation(x, y); Draw(canvas, ref matrix); } public SKPicture Snapshot() { return SKPicture.GetObject(SkiaApi.sk_drawable_new_picture_snapshot(Handle), owns: true, unrefExisting: false); } public void NotifyDrawingChanged() { SkiaApi.sk_drawable_notify_drawing_changed(Handle); } protected virtual void OnDraw(SKCanvas canvas) { } protected virtual SKRect OnGetBounds() { return SKRect.Empty; } protected virtual SKPicture OnSnapshot() { using SKPictureRecorder sKPictureRecorder = new SKPictureRecorder(); SKCanvas canvas = sKPictureRecorder.BeginRecording(Bounds); Draw(canvas, 0f, 0f); return sKPictureRecorder.EndRecording(); } [MonoPInvokeCallback(typeof(SKManagedDrawableDrawProxyDelegate))] private unsafe static void DrawInternal(IntPtr d, void* context, IntPtr canvas) { GCHandle gch; SKDrawable userData = DelegateProxies.GetUserData((IntPtr)context, out gch); userData.OnDraw(SKCanvas.GetObject(canvas, owns: false)); } [MonoPInvokeCallback(typeof(SKManagedDrawableGetBoundsProxyDelegate))] private unsafe static void GetBoundsInternal(IntPtr d, void* context, SKRect* rect) { GCHandle gch; SKDrawable userData = DelegateProxies.GetUserData((IntPtr)context, out gch); SKRect sKRect = userData.OnGetBounds(); *rect = sKRect; } [MonoPInvokeCallback(typeof(SKManagedDrawableNewPictureSnapshotProxyDelegate))] private unsafe static IntPtr NewPictureSnapshotInternal(IntPtr d, void* context) { GCHandle gch; SKDrawable userData = DelegateProxies.GetUserData((IntPtr)context, out gch); return userData.OnSnapshot()?.Handle ?? IntPtr.Zero; } [MonoPInvokeCallback(typeof(SKManagedDrawableDestroyProxyDelegate))] private unsafe static void DestroyInternal(IntPtr d, void* context) { GCHandle gch; SKDrawable userData = DelegateProxies.GetUserData((IntPtr)context, out gch); if (userData != null) { Interlocked.Exchange(ref userData.fromNative, 1); userData.Dispose(); } gch.Free(); } internal static SKDrawable GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKDrawable(h, o)); } } public class SKFont : SKObject { internal sealed class GlyphPathCache : Dictionary, IDisposable { public SKFont Font { get; } public GlyphPathCache(SKFont font) { Font = font; } public SKPath GetPath(ushort glyph) { if (!TryGetValue(glyph, out var value)) { value = (base[glyph] = Font.GetGlyphPath(glyph)); } return value; } public void Dispose() { foreach (SKPath value in base.Values) { value?.Dispose(); } Clear(); } } internal const float DefaultSize = 12f; internal const float DefaultScaleX = 1f; internal const float DefaultSkewX = 0f; public bool ForceAutoHinting { get { return SkiaApi.sk_font_is_force_auto_hinting(Handle); } set { SkiaApi.sk_font_set_force_auto_hinting(Handle, value); } } public bool EmbeddedBitmaps { get { return SkiaApi.sk_font_is_embedded_bitmaps(Handle); } set { SkiaApi.sk_font_set_embedded_bitmaps(Handle, value); } } public bool Subpixel { get { return SkiaApi.sk_font_is_subpixel(Handle); } set { SkiaApi.sk_font_set_subpixel(Handle, value); } } public bool LinearMetrics { get { return SkiaApi.sk_font_is_linear_metrics(Handle); } set { SkiaApi.sk_font_set_linear_metrics(Handle, value); } } public bool Embolden { get { return SkiaApi.sk_font_is_embolden(Handle); } set { SkiaApi.sk_font_set_embolden(Handle, value); } } public bool BaselineSnap { get { return SkiaApi.sk_font_is_baseline_snap(Handle); } set { SkiaApi.sk_font_set_baseline_snap(Handle, value); } } public SKFontEdging Edging { get { return SkiaApi.sk_font_get_edging(Handle); } set { SkiaApi.sk_font_set_edging(Handle, value); } } public SKFontHinting Hinting { get { return SkiaApi.sk_font_get_hinting(Handle); } set { SkiaApi.sk_font_set_hinting(Handle, value); } } public SKTypeface Typeface { get { return SKTypeface.GetObject(SkiaApi.sk_font_get_typeface(Handle)); } set { SkiaApi.sk_font_set_typeface(Handle, value?.Handle ?? IntPtr.Zero); } } public float Size { get { return SkiaApi.sk_font_get_size(Handle); } set { SkiaApi.sk_font_set_size(Handle, value); } } public float ScaleX { get { return SkiaApi.sk_font_get_scale_x(Handle); } set { SkiaApi.sk_font_set_scale_x(Handle, value); } } public float SkewX { get { return SkiaApi.sk_font_get_skew_x(Handle); } set { SkiaApi.sk_font_set_skew_x(Handle, value); } } public unsafe float Spacing => SkiaApi.sk_font_get_metrics(Handle, null); public SKFontMetrics Metrics { get { GetFontMetrics(out var metrics); return metrics; } } internal SKFont(IntPtr handle, bool owns) : base(handle, owns) { } public SKFont() : this(SkiaApi.sk_font_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKFont instance."); } } public SKFont(SKTypeface typeface, float size = 12f, float scaleX = 1f, float skewX = 0f) : this(SkiaApi.sk_font_new_with_values(typeface?.Handle ?? IntPtr.Zero, size, scaleX, skewX), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKFont instance."); } } protected override void DisposeNative() { SkiaApi.sk_font_delete(Handle); } public unsafe float GetFontMetrics(out SKFontMetrics metrics) { fixed (SKFontMetrics* metrics2 = &metrics) { return SkiaApi.sk_font_get_metrics(Handle, metrics2); } } public ushort GetGlyph(int codepoint) { return SkiaApi.sk_font_unichar_to_glyph(Handle, codepoint); } internal ushort[] GetGlyphs(ReadOnlySpan codepoints) { ushort[] array = new ushort[codepoints.Length]; GetGlyphs(codepoints, array); return array; } public unsafe void GetGlyphs(ReadOnlySpan codepoints, Span glyphs) { if (codepoints.IsEmpty) { return; } if (glyphs.Length != codepoints.Length) { throw new ArgumentException("The length of glyphs must be the same as the length of codepoints.", "glyphs"); } fixed (int* uni = codepoints) { fixed (ushort* glyphs2 = glyphs) { SkiaApi.sk_font_unichars_to_glyphs(Handle, uni, codepoints.Length, glyphs2); } } } internal ushort[] GetGlyphs(string text) { return GetGlyphs(text.AsSpan()); } internal unsafe ushort[] GetGlyphs(ReadOnlySpan text) { fixed (char* ptr = text) { void* text2 = ptr; return GetGlyphs(text2, text.Length * 2, SKTextEncoding.Utf16); } } internal unsafe ushort[] GetGlyphs(ReadOnlySpan text, SKTextEncoding encoding) { fixed (byte* ptr = text) { void* text2 = ptr; return GetGlyphs(text2, text.Length, encoding); } } internal unsafe ushort[] GetGlyphs(IntPtr text, int length, SKTextEncoding encoding) { return GetGlyphs((void*)text, length, encoding); } public void GetGlyphs(string text, Span glyphs) { GetGlyphs(text.AsSpan(), glyphs); } public unsafe void GetGlyphs(ReadOnlySpan text, Span glyphs) { fixed (char* ptr = text) { void* text2 = ptr; GetGlyphs(text2, text.Length * 2, SKTextEncoding.Utf16, glyphs); } } public unsafe void GetGlyphs(ReadOnlySpan text, SKTextEncoding encoding, Span glyphs) { fixed (byte* ptr = text) { void* text2 = ptr; GetGlyphs(text2, text.Length, encoding, glyphs); } } public unsafe void GetGlyphs(IntPtr text, int length, SKTextEncoding encoding, Span glyphs) { GetGlyphs((void*)text, length, encoding, glyphs); } internal unsafe ushort[] GetGlyphs(void* text, int length, SKTextEncoding encoding) { if (!ValidateTextArgs(text, length, encoding)) { return new ushort[0]; } int num = CountGlyphs(text, length, encoding); if (num <= 0) { return new ushort[0]; } ushort[] array = new ushort[num]; GetGlyphs(text, length, encoding, array); return array; } internal unsafe void GetGlyphs(void* text, int length, SKTextEncoding encoding, Span glyphs) { if (ValidateTextArgs(text, length, encoding)) { fixed (ushort* glyphs2 = glyphs) { SkiaApi.sk_font_text_to_glyphs(Handle, text, (IntPtr)length, encoding, glyphs2, glyphs.Length); } } } public bool ContainsGlyph(int codepoint) { return GetGlyph(codepoint) != 0; } public bool ContainsGlyphs(ReadOnlySpan codepoints) { return ContainsGlyphs(GetGlyphs(codepoints)); } public bool ContainsGlyphs(string text) { return ContainsGlyphs(GetGlyphs(text)); } public bool ContainsGlyphs(ReadOnlySpan text) { return ContainsGlyphs(GetGlyphs(text)); } public bool ContainsGlyphs(ReadOnlySpan text, SKTextEncoding encoding) { return ContainsGlyphs(GetGlyphs(text, encoding)); } public bool ContainsGlyphs(IntPtr text, int length, SKTextEncoding encoding) { return ContainsGlyphs(GetGlyphs(text, length, encoding)); } private bool ContainsGlyphs(ushort[] glyphs) { return Array.IndexOf(glyphs, (ushort)0) == -1; } public int CountGlyphs(string text) { return CountGlyphs(text.AsSpan()); } public unsafe int CountGlyphs(ReadOnlySpan text) { fixed (char* ptr = text) { void* text2 = ptr; return CountGlyphs(text2, text.Length * 2, SKTextEncoding.Utf16); } } public unsafe int CountGlyphs(ReadOnlySpan text, SKTextEncoding encoding) { fixed (byte* ptr = text) { void* text2 = ptr; return CountGlyphs(text2, text.Length, encoding); } } public unsafe int CountGlyphs(IntPtr text, int length, SKTextEncoding encoding) { return CountGlyphs((void*)text, length, encoding); } internal unsafe int CountGlyphs(void* text, int length, SKTextEncoding encoding) { if (!ValidateTextArgs(text, length, encoding)) { return 0; } return SkiaApi.sk_font_text_to_glyphs(Handle, text, (IntPtr)length, encoding, null, 0); } internal float MeasureText(string text, SKPaint paint = null) { return MeasureText(text.AsSpan(), paint); } internal unsafe float MeasureText(ReadOnlySpan text, SKPaint paint = null) { fixed (char* ptr = text) { void* text2 = ptr; return MeasureText(text2, text.Length * 2, SKTextEncoding.Utf16, null, paint); } } internal unsafe float MeasureText(ReadOnlySpan text, SKTextEncoding encoding, SKPaint paint = null) { fixed (byte* ptr = text) { void* text2 = ptr; return MeasureText(text2, text.Length, encoding, null, paint); } } internal unsafe float MeasureText(IntPtr text, int length, SKTextEncoding encoding, SKPaint paint = null) { return MeasureText((void*)text, length, encoding, null, paint); } internal float MeasureText(string text, out SKRect bounds, SKPaint paint = null) { return MeasureText(text.AsSpan(), out bounds, paint); } internal unsafe float MeasureText(ReadOnlySpan text, out SKRect bounds, SKPaint paint = null) { fixed (char* ptr = text) { void* text2 = ptr; fixed (SKRect* bounds2 = &bounds) { return MeasureText(text2, text.Length * 2, SKTextEncoding.Utf16, bounds2, paint); } } } internal unsafe float MeasureText(ReadOnlySpan text, SKTextEncoding encoding, out SKRect bounds, SKPaint paint = null) { fixed (byte* ptr = text) { void* text2 = ptr; fixed (SKRect* bounds2 = &bounds) { return MeasureText(text2, text.Length, encoding, bounds2, paint); } } } internal unsafe float MeasureText(IntPtr text, int length, SKTextEncoding encoding, out SKRect bounds, SKPaint paint = null) { fixed (SKRect* bounds2 = &bounds) { return MeasureText((void*)text, length, encoding, bounds2, paint); } } internal unsafe float MeasureText(void* text, int length, SKTextEncoding encoding, SKRect* bounds, SKPaint paint) { if (!ValidateTextArgs(text, length, encoding)) { return 0f; } float result = default(float); SkiaApi.sk_font_measure_text_no_return(Handle, text, (IntPtr)length, encoding, bounds, paint?.Handle ?? IntPtr.Zero, &result); return result; } public unsafe float MeasureText(ReadOnlySpan glyphs, SKPaint paint = null) { fixed (ushort* text = glyphs) { return MeasureText(text, glyphs.Length * 2, SKTextEncoding.GlyphId, null, paint); } } public unsafe float MeasureText(ReadOnlySpan glyphs, out SKRect bounds, SKPaint paint = null) { fixed (ushort* text = glyphs) { fixed (SKRect* bounds2 = &bounds) { return MeasureText(text, glyphs.Length * 2, SKTextEncoding.GlyphId, bounds2, paint); } } } internal int BreakText(string text, float maxWidth, out float measuredWidth, SKPaint paint = null) { return BreakText(text.AsSpan(), maxWidth, out measuredWidth, paint); } internal unsafe int BreakText(ReadOnlySpan text, float maxWidth, out float measuredWidth, SKPaint paint = null) { fixed (char* ptr = text) { void* text2 = ptr; fixed (float* measuredWidth2 = &measuredWidth) { int num = BreakText(text2, text.Length * 2, SKTextEncoding.Utf16, maxWidth, measuredWidth2, paint); return num / 2; } } } internal unsafe int BreakText(ReadOnlySpan text, SKTextEncoding encoding, float maxWidth, out float measuredWidth, SKPaint paint = null) { fixed (byte* ptr = text) { void* text2 = ptr; fixed (float* measuredWidth2 = &measuredWidth) { return BreakText(text2, text.Length, encoding, maxWidth, measuredWidth2, paint); } } } internal unsafe int BreakText(IntPtr text, int length, SKTextEncoding encoding, float maxWidth, out float measuredWidth, SKPaint paint = null) { fixed (float* measuredWidth2 = &measuredWidth) { return BreakText((void*)text, length, encoding, maxWidth, measuredWidth2, paint); } } internal unsafe int BreakText(void* text, int length, SKTextEncoding encoding, float maxWidth, float* measuredWidth, SKPaint paint) { if (!ValidateTextArgs(text, length, encoding)) { return 0; } return (int)SkiaApi.sk_font_break_text(Handle, text, (IntPtr)length, encoding, maxWidth, measuredWidth, paint?.Handle ?? IntPtr.Zero); } internal SKPoint[] GetGlyphPositions(string text, SKPoint origin = default(SKPoint)) { return GetGlyphPositions(text.AsSpan(), origin); } internal unsafe SKPoint[] GetGlyphPositions(ReadOnlySpan text, SKPoint origin = default(SKPoint)) { fixed (char* ptr = text) { void* text2 = ptr; return GetGlyphPositions(text2, text.Length * 2, SKTextEncoding.Utf16, origin); } } internal unsafe SKPoint[] GetGlyphPositions(ReadOnlySpan text, SKTextEncoding encoding, SKPoint origin = default(SKPoint)) { fixed (byte* ptr = text) { void* text2 = ptr; return GetGlyphPositions(text2, text.Length, encoding, origin); } } internal unsafe SKPoint[] GetGlyphPositions(IntPtr text, int length, SKTextEncoding encoding, SKPoint origin = default(SKPoint)) { return GetGlyphPositions((void*)text, length, encoding, origin); } internal void GetGlyphPositions(string text, Span offsets, SKPoint origin = default(SKPoint)) { GetGlyphPositions(text.AsSpan(), offsets, origin); } internal unsafe void GetGlyphPositions(ReadOnlySpan text, Span offsets, SKPoint origin = default(SKPoint)) { fixed (char* ptr = text) { void* text2 = ptr; GetGlyphPositions(text2, text.Length * 2, SKTextEncoding.Utf16, offsets, origin); } } internal unsafe void GetGlyphPositions(ReadOnlySpan text, SKTextEncoding encoding, Span offsets, SKPoint origin = default(SKPoint)) { fixed (byte* ptr = text) { void* text2 = ptr; GetGlyphPositions(text2, text.Length, encoding, offsets, origin); } } internal unsafe void GetGlyphPositions(IntPtr text, int length, SKTextEncoding encoding, Span offsets, SKPoint origin = default(SKPoint)) { GetGlyphPositions((void*)text, length, encoding, offsets, origin); } internal unsafe SKPoint[] GetGlyphPositions(void* text, int length, SKTextEncoding encoding, SKPoint origin) { if (!ValidateTextArgs(text, length, encoding)) { return new SKPoint[0]; } int num = CountGlyphs(text, length, encoding); if (num <= 0) { return new SKPoint[0]; } SKPoint[] array = new SKPoint[num]; GetGlyphPositions(text, length, encoding, array, origin); return array; } internal unsafe void GetGlyphPositions(void* text, int length, SKTextEncoding encoding, Span offsets, SKPoint origin) { if (!ValidateTextArgs(text, length, encoding)) { return; } int length2 = offsets.Length; if (length2 <= 0) { return; } Utils.RentedArray rentedArray = Utils.RentArray(length2); try { GetGlyphs(text, length, encoding, rentedArray); GetGlyphPositions(rentedArray, offsets, origin); } finally { rentedArray.Dispose(); } } internal SKPoint[] GetGlyphPositions(ReadOnlySpan glyphs, SKPoint origin = default(SKPoint)) { SKPoint[] array = new SKPoint[glyphs.Length]; GetGlyphPositions(glyphs, array, origin); return array; } public unsafe void GetGlyphPositions(ReadOnlySpan glyphs, Span positions, SKPoint origin = default(SKPoint)) { if (glyphs.Length != positions.Length) { throw new ArgumentException("The length of glyphs must be the same as the length of positions.", "positions"); } fixed (ushort* glyphs2 = glyphs) { fixed (SKPoint* pos = positions) { SkiaApi.sk_font_get_pos(Handle, glyphs2, glyphs.Length, pos, &origin); } } } internal float[] GetGlyphOffsets(string text, float origin = 0f) { return GetGlyphOffsets(text.AsSpan(), origin); } internal unsafe float[] GetGlyphOffsets(ReadOnlySpan text, float origin = 0f) { fixed (char* ptr = text) { void* text2 = ptr; return GetGlyphOffsets(text2, text.Length * 2, SKTextEncoding.Utf16, origin); } } internal unsafe float[] GetGlyphOffsets(ReadOnlySpan text, SKTextEncoding encoding, float origin = 0f) { fixed (byte* ptr = text) { void* text2 = ptr; return GetGlyphOffsets(text2, text.Length, encoding, origin); } } internal unsafe float[] GetGlyphOffsets(IntPtr text, int length, SKTextEncoding encoding, float origin = 0f) { return GetGlyphOffsets((void*)text, length, encoding, origin); } internal void GetGlyphOffsets(string text, Span offsets, float origin = 0f) { GetGlyphOffsets(text.AsSpan(), offsets, origin); } internal unsafe void GetGlyphOffsets(ReadOnlySpan text, Span offsets, float origin = 0f) { fixed (char* ptr = text) { void* text2 = ptr; GetGlyphOffsets(text2, text.Length * 2, SKTextEncoding.Utf16, offsets, origin); } } internal unsafe void GetGlyphOffsets(ReadOnlySpan text, SKTextEncoding encoding, Span offsets, float origin = 0f) { fixed (byte* ptr = text) { void* text2 = ptr; GetGlyphOffsets(text2, text.Length, encoding, offsets, origin); } } internal unsafe void GetGlyphOffsets(IntPtr text, int length, SKTextEncoding encoding, Span offsets, float origin = 0f) { GetGlyphOffsets((void*)text, length, encoding, offsets, origin); } internal unsafe float[] GetGlyphOffsets(void* text, int length, SKTextEncoding encoding, float origin) { if (!ValidateTextArgs(text, length, encoding)) { return new float[0]; } int num = CountGlyphs(text, length, encoding); if (num <= 0) { return new float[0]; } float[] array = new float[num]; GetGlyphOffsets(text, length, encoding, array, origin); return array; } internal unsafe void GetGlyphOffsets(void* text, int length, SKTextEncoding encoding, Span offsets, float origin) { if (!ValidateTextArgs(text, length, encoding)) { return; } int length2 = offsets.Length; if (length2 <= 0) { return; } Utils.RentedArray rentedArray = Utils.RentArray(length2); try { GetGlyphs(text, length, encoding, rentedArray); GetGlyphOffsets(rentedArray, offsets, origin); } finally { rentedArray.Dispose(); } } internal float[] GetGlyphOffsets(ReadOnlySpan glyphs, float origin = 0f) { float[] array = new float[glyphs.Length]; GetGlyphOffsets(glyphs, array, origin); return array; } public unsafe void GetGlyphOffsets(ReadOnlySpan glyphs, Span offsets, float origin = 0f) { if (glyphs.Length != offsets.Length) { throw new ArgumentException("The length of glyphs must be the same as the length of offsets.", "offsets"); } fixed (ushort* glyphs2 = glyphs) { fixed (float* xpos = offsets) { SkiaApi.sk_font_get_xpos(Handle, glyphs2, glyphs.Length, xpos, origin); } } } internal float[] GetGlyphWidths(string text, SKPaint paint = null) { return GetGlyphWidths(text.AsSpan(), paint); } internal unsafe float[] GetGlyphWidths(ReadOnlySpan text, SKPaint paint = null) { fixed (char* ptr = text) { void* text2 = ptr; return GetGlyphWidths(text2, text.Length * 2, SKTextEncoding.Utf16, paint); } } internal unsafe float[] GetGlyphWidths(ReadOnlySpan text, SKTextEncoding encoding, SKPaint paint = null) { fixed (byte* ptr = text) { void* text2 = ptr; return GetGlyphWidths(text2, text.Length, encoding, paint); } } internal unsafe float[] GetGlyphWidths(IntPtr text, int length, SKTextEncoding encoding, SKPaint paint = null) { return GetGlyphWidths((void*)text, length, encoding, paint); } internal float[] GetGlyphWidths(string text, out SKRect[] bounds, SKPaint paint = null) { return GetGlyphWidths(text.AsSpan(), out bounds, paint); } internal unsafe float[] GetGlyphWidths(ReadOnlySpan text, out SKRect[] bounds, SKPaint paint = null) { fixed (char* ptr = text) { void* text2 = ptr; return GetGlyphWidths(text2, text.Length * 2, SKTextEncoding.Utf16, out bounds, paint); } } internal unsafe float[] GetGlyphWidths(ReadOnlySpan text, SKTextEncoding encoding, out SKRect[] bounds, SKPaint paint = null) { fixed (byte* ptr = text) { void* text2 = ptr; return GetGlyphWidths(text2, text.Length, encoding, out bounds, paint); } } internal unsafe float[] GetGlyphWidths(IntPtr text, int length, SKTextEncoding encoding, out SKRect[] bounds, SKPaint paint = null) { return GetGlyphWidths((void*)text, length, encoding, out bounds, paint); } internal void GetGlyphWidths(string text, Span widths, Span bounds, SKPaint paint = null) { GetGlyphWidths(text.AsSpan(), widths, bounds, paint); } internal unsafe void GetGlyphWidths(ReadOnlySpan text, Span widths, Span bounds, SKPaint paint = null) { fixed (char* ptr = text) { void* text2 = ptr; GetGlyphWidths(text2, text.Length * 2, SKTextEncoding.Utf16, widths, bounds, paint); } } internal unsafe void GetGlyphWidths(ReadOnlySpan text, SKTextEncoding encoding, Span widths, Span bounds, SKPaint paint = null) { fixed (byte* ptr = text) { void* text2 = ptr; GetGlyphWidths(text2, text.Length, encoding, widths, bounds, paint); } } internal unsafe void GetGlyphWidths(IntPtr text, int length, SKTextEncoding encoding, Span widths, Span bounds, SKPaint paint = null) { GetGlyphWidths((void*)text, length, encoding, widths, bounds, paint); } internal unsafe float[] GetGlyphWidths(void* text, int length, SKTextEncoding encoding, SKPaint paint) { if (!ValidateTextArgs(text, length, encoding)) { return new float[0]; } int num = CountGlyphs(text, length, encoding); if (num <= 0) { return new float[0]; } float[] array = new float[num]; GetGlyphWidths(text, length, encoding, array, Span.Empty, paint); return array; } internal unsafe float[] GetGlyphWidths(void* text, int length, SKTextEncoding encoding, out SKRect[] bounds, SKPaint paint) { if (!ValidateTextArgs(text, length, encoding)) { bounds = new SKRect[0]; return new float[0]; } int num = CountGlyphs(text, length, encoding); if (num <= 0) { bounds = new SKRect[0]; return new float[0]; } bounds = new SKRect[num]; float[] array = new float[num]; GetGlyphWidths(text, length, encoding, array, bounds, paint); return array; } internal unsafe void GetGlyphWidths(void* text, int length, SKTextEncoding encoding, Span widths, Span bounds, SKPaint paint) { if (!ValidateTextArgs(text, length, encoding)) { return; } int num = Math.Max(widths.Length, bounds.Length); if (num <= 0) { return; } if (widths.Length != 0 && widths.Length != num) { throw new ArgumentException("The length of widths must be equal to the length of bounds or empty.", "widths"); } if (bounds.Length != 0 && bounds.Length != num) { throw new ArgumentException("The length of bounds must be equal to the length of widths or empty.", "bounds"); } Utils.RentedArray rentedArray = Utils.RentArray(num); try { GetGlyphs(text, length, encoding, rentedArray); GetGlyphWidths(rentedArray, widths, bounds, paint); } finally { rentedArray.Dispose(); } } internal float[] GetGlyphWidths(ReadOnlySpan glyphs, SKPaint paint = null) { float[] array = new float[glyphs.Length]; GetGlyphWidths(glyphs, array, Span.Empty, paint); return array; } internal float[] GetGlyphWidths(ReadOnlySpan glyphs, out SKRect[] bounds, SKPaint paint = null) { float[] array = new float[glyphs.Length]; bounds = new SKRect[glyphs.Length]; GetGlyphWidths(glyphs, array, bounds, paint); return array; } public unsafe void GetGlyphWidths(ReadOnlySpan glyphs, Span widths, Span bounds, SKPaint paint = null) { fixed (ushort* glyphs2 = glyphs) { fixed (float* ptr = widths) { fixed (SKRect* ptr2 = bounds) { float* widths2 = ((widths.Length > 0) ? ptr : null); SKRect* bounds2 = ((bounds.Length > 0) ? ptr2 : null); SkiaApi.sk_font_get_widths_bounds(Handle, glyphs2, glyphs.Length, widths2, bounds2, paint?.Handle ?? IntPtr.Zero); } } } } public SKPath GetGlyphPath(ushort glyph) { SKPath sKPath = new SKPath(); if (!SkiaApi.sk_font_get_path(Handle, glyph, sKPath.Handle)) { sKPath.Dispose(); sKPath = null; } return sKPath; } internal SKPath GetTextPath(string text, SKPoint origin = default(SKPoint)) { return GetTextPath(text.AsSpan(), origin); } internal unsafe SKPath GetTextPath(ReadOnlySpan text, SKPoint origin = default(SKPoint)) { fixed (char* ptr = text) { void* text2 = ptr; return GetTextPath(text2, text.Length * 2, SKTextEncoding.Utf16, origin); } } internal unsafe SKPath GetTextPath(ReadOnlySpan text, SKTextEncoding encoding, SKPoint origin = default(SKPoint)) { fixed (byte* ptr = text) { void* text2 = ptr; return GetTextPath(text2, text.Length, encoding, origin); } } internal unsafe SKPath GetTextPath(IntPtr text, int length, SKTextEncoding encoding, SKPoint origin = default(SKPoint)) { return GetTextPath((void*)text, length, encoding, origin); } internal unsafe SKPath GetTextPath(void* text, int length, SKTextEncoding encoding, SKPoint origin) { if (!ValidateTextArgs(text, length, encoding)) { return new SKPath(); } SKPath sKPath = new SKPath(); SkiaApi.sk_text_utils_get_path(text, (IntPtr)length, encoding, origin.X, origin.Y, Handle, sKPath.Handle); return sKPath; } internal SKPath GetTextPath(string text, ReadOnlySpan positions) { return GetTextPath(text.AsSpan(), positions); } internal unsafe SKPath GetTextPath(ReadOnlySpan text, ReadOnlySpan positions) { fixed (char* ptr = text) { void* text2 = ptr; return GetTextPath(text2, text.Length * 2, SKTextEncoding.Utf16, positions); } } internal unsafe SKPath GetTextPath(ReadOnlySpan text, SKTextEncoding encoding, ReadOnlySpan positions) { fixed (byte* ptr = text) { void* text2 = ptr; return GetTextPath(text2, text.Length, encoding, positions); } } internal unsafe SKPath GetTextPath(IntPtr text, int length, SKTextEncoding encoding, ReadOnlySpan positions) { return GetTextPath((void*)text, length, encoding, positions); } internal unsafe SKPath GetTextPath(void* text, int length, SKTextEncoding encoding, ReadOnlySpan positions) { if (!ValidateTextArgs(text, length, encoding)) { return new SKPath(); } SKPath sKPath = new SKPath(); fixed (SKPoint* pos = positions) { SkiaApi.sk_text_utils_get_pos_path(text, (IntPtr)length, encoding, pos, Handle, sKPath.Handle); } return sKPath; } public unsafe void GetGlyphPaths(ReadOnlySpan glyphs, SKGlyphPathDelegate glyphPathDelegate) { GCHandle gch; IntPtr contextPtr; SKGlyphPathProxyDelegate glyphPathProc = DelegateProxies.Create(glyphPathDelegate, DelegateProxies.SKGlyphPathDelegateProxy, out gch, out contextPtr); try { fixed (ushort* glyphs2 = glyphs) { SkiaApi.sk_font_get_paths(Handle, glyphs2, glyphs.Length, glyphPathProc, (void*)contextPtr); } } finally { gch.Free(); } } internal SKPath GetTextPathOnPath(string text, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { return GetTextPathOnPath(text.AsSpan(), path, textAlign, origin); } internal unsafe SKPath GetTextPathOnPath(ReadOnlySpan text, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { fixed (char* ptr = text) { void* text2 = ptr; return GetTextPathOnPath(text2, text.Length * 2, SKTextEncoding.Utf16, path, textAlign, origin); } } internal unsafe SKPath GetTextPathOnPath(ReadOnlySpan text, SKTextEncoding encoding, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { fixed (byte* ptr = text) { void* text2 = ptr; return GetTextPathOnPath(text2, text.Length, encoding, path, textAlign, origin); } } internal unsafe SKPath GetTextPathOnPath(IntPtr text, int length, SKTextEncoding encoding, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { return GetTextPathOnPath((void*)text, length, encoding, path, textAlign, origin); } internal unsafe SKPath GetTextPathOnPath(void* text, int length, SKTextEncoding encoding, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { if (!ValidateTextArgs(text, length, encoding)) { return new SKPath(); } int num = CountGlyphs(text, length, encoding); if (num <= 0) { return new SKPath(); } Utils.RentedArray rentedArray = Utils.RentArray(num); try { GetGlyphs(text, length, encoding, rentedArray); return GetTextPathOnPath(rentedArray, path, textAlign, origin); } finally { rentedArray.Dispose(); } } internal SKPath GetTextPathOnPath(ReadOnlySpan glyphs, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { if (path == null) { throw new ArgumentNullException("path"); } if (glyphs.Length == 0) { return new SKPath(); } Utils.RentedArray rentedArray = Utils.RentArray(glyphs.Length); try { Utils.RentedArray rentedArray2 = Utils.RentArray(glyphs.Length); try { GetGlyphWidths(glyphs, rentedArray, Span.Empty); GetGlyphPositions(glyphs, rentedArray2, origin); return GetTextPathOnPath(glyphs, rentedArray, rentedArray2, path, textAlign); } finally { rentedArray2.Dispose(); } } finally { rentedArray.Dispose(); } } internal SKPath GetTextPathOnPath(ReadOnlySpan glyphs, ReadOnlySpan glyphWidths, ReadOnlySpan glyphPositions, SKPath path, SKTextAlign textAlign = SKTextAlign.Left) { if (glyphs.Length != glyphWidths.Length) { throw new ArgumentException("The number of glyphs and glyph widths must be the same."); } if (glyphs.Length != glyphPositions.Length) { throw new ArgumentException("The number of glyphs and glyph offsets must be the same."); } if (path == null) { throw new ArgumentNullException("path"); } if (glyphs.Length == 0) { return new SKPath(); } using (GlyphPathCache glyphPathCache = new GlyphPathCache(this)) { using SKPathMeasure sKPathMeasure = new SKPathMeasure(path); float length = sKPathMeasure.Length; float num = glyphPositions[glyphs.Length - 1].X + glyphWidths[glyphs.Length - 1]; float num2 = (float)textAlign * 0.5f; float num3 = glyphPositions[0].X + (length - num) * num2; SKPath sKPath = new SKPath(); for (int i = 0; i < glyphPositions.Length; i++) { SKPoint sKPoint = glyphPositions[i]; float num4 = glyphWidths[i]; float num5 = num3 + sKPoint.X; float num6 = num5 + num4; if (num6 >= 0f && num5 <= length) { ushort glyph = glyphs[i]; SKPath path2 = glyphPathCache.GetPath(glyph); if (path2 != null) { MorphPath(sKPath, path2, sKPathMeasure, SKMatrix.CreateTranslation(num5, sKPoint.Y)); } } } return sKPath; } static void MorphPath(SKPath dst, SKPath src, SKPathMeasure meas, in SKMatrix matrix) { using SKPath.Iterator iterator = src.CreateIterator(forceClose: false); Span span = stackalloc SKPoint[4]; Span dst2 = stackalloc SKPoint[4]; SKPathVerb sKPathVerb; while ((sKPathVerb = iterator.Next(span)) != SKPathVerb.Done) { switch (sKPathVerb) { case SKPathVerb.Move: MorphPoints(dst2, span, 1, meas, in matrix); dst.MoveTo(dst2[0]); break; case SKPathVerb.Line: span[0].X = (span[0].X + span[1].X) * 0.5f; span[0].Y = (span[0].Y + span[1].Y) * 0.5f; MorphPoints(dst2, span, 2, meas, in matrix); dst.QuadTo(dst2[0], dst2[1]); break; case SKPathVerb.Quad: MorphPoints(dst2, span.Slice(1, 2), 2, meas, in matrix); dst.QuadTo(dst2[0], dst2[1]); break; case SKPathVerb.Conic: MorphPoints(dst2, span.Slice(1, 2), 2, meas, in matrix); dst.ConicTo(dst2[0], dst2[1], iterator.ConicWeight()); break; case SKPathVerb.Cubic: MorphPoints(dst2, span.Slice(1, 3), 3, meas, in matrix); dst.CubicTo(dst2[0], dst2[1], dst2[2]); break; case SKPathVerb.Close: dst.Close(); break; } } } static void MorphPoints(Span dst, Span src, int count, SKPathMeasure meas, in SKMatrix matrix) { for (int j = 0; j < count; j++) { SKPoint sKPoint2 = matrix.MapPoint(src[j].X, src[j].Y); if (!meas.GetPositionAndTangent(sKPoint2.X, out var position, out var tangent)) { tangent = SKPoint.Empty; } dst[j] = new SKPoint(position.X - tangent.Y * sKPoint2.Y, position.Y + tangent.X * sKPoint2.Y); } } } private unsafe bool ValidateTextArgs(void* text, int length, SKTextEncoding encoding) { if (length == 0) { return false; } if (text == null) { throw new ArgumentNullException("text"); } return true; } internal static SKFont GetObject(IntPtr handle, bool owns = true) { return SKObject.GetOrAddObject(handle, owns, (IntPtr h, bool o) => new SKFont(h, o)); } } public class SKFontManager : SKObject, ISKReferenceCounted { private sealed class SKFontManagerStatic : SKFontManager { internal SKFontManagerStatic(IntPtr x) : base(x, owns: false) { } protected override void Dispose(bool disposing) { } } private static readonly SKFontManager defaultManager; public static SKFontManager Default => defaultManager; public int FontFamilyCount => SkiaApi.sk_fontmgr_count_families(Handle); public IEnumerable FontFamilies { get { int count = FontFamilyCount; for (int i = 0; i < count; i++) { yield return GetFamilyName(i); } } } static SKFontManager() { defaultManager = new SKFontManagerStatic(SkiaApi.sk_fontmgr_ref_default()); } internal static void EnsureStaticInstanceAreInitialized() { } internal SKFontManager(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public string GetFamilyName(int index) { using SKString sKString = new SKString(); SkiaApi.sk_fontmgr_get_family_name(Handle, index, sKString.Handle); return (string)sKString; } public string[] GetFontFamilies() { return FontFamilies.ToArray(); } public SKFontStyleSet GetFontStyles(int index) { return SKFontStyleSet.GetObject(SkiaApi.sk_fontmgr_create_styleset(Handle, index)); } public unsafe SKFontStyleSet GetFontStyles(string familyName) { fixed (byte* encodedText = StringUtilities.GetEncodedText(familyName, SKTextEncoding.Utf8, addNull: true)) { return SKFontStyleSet.GetObject(SkiaApi.sk_fontmgr_match_family(Handle, new IntPtr(encodedText))); } } public SKTypeface MatchFamily(string familyName) { return MatchFamily(familyName, SKFontStyle.Normal); } public unsafe SKTypeface MatchFamily(string familyName, SKFontStyle style) { if (style == null) { throw new ArgumentNullException("style"); } fixed (byte* encodedText = StringUtilities.GetEncodedText(familyName, SKTextEncoding.Utf8, addNull: true)) { SKTypeface sKTypeface = SKTypeface.GetObject(SkiaApi.sk_fontmgr_match_family_style(Handle, new IntPtr(encodedText), style.Handle)); sKTypeface?.PreventPublicDisposal(); return sKTypeface; } } public SKTypeface MatchTypeface(SKTypeface face, SKFontStyle style) { if (face == null) { throw new ArgumentNullException("face"); } if (style == null) { throw new ArgumentNullException("style"); } SKTypeface sKTypeface = SKTypeface.GetObject(SkiaApi.sk_fontmgr_match_face_style(Handle, face.Handle, style.Handle)); sKTypeface?.PreventPublicDisposal(); return sKTypeface; } public unsafe SKTypeface CreateTypeface(string path, int index = 0) { if (path == null) { throw new ArgumentNullException("path"); } fixed (byte* encodedText = StringUtilities.GetEncodedText(path, SKTextEncoding.Utf8, addNull: true)) { return SKTypeface.GetObject(SkiaApi.sk_fontmgr_create_from_file(Handle, encodedText, index)); } } public SKTypeface CreateTypeface(Stream stream, int index = 0) { if (stream == null) { throw new ArgumentNullException("stream"); } return CreateTypeface(new SKManagedStream(stream, disposeManagedStream: true), index); } public SKTypeface CreateTypeface(SKStreamAsset stream, int index = 0) { if (stream == null) { throw new ArgumentNullException("stream"); } if (stream is SKManagedStream sKManagedStream) { stream = sKManagedStream.ToMemoryStream(); sKManagedStream.Dispose(); } SKTypeface sKTypeface = SKTypeface.GetObject(SkiaApi.sk_fontmgr_create_from_stream(Handle, stream.Handle, index)); stream.RevokeOwnership(sKTypeface); return sKTypeface; } public SKTypeface CreateTypeface(SKData data, int index = 0) { if (data == null) { throw new ArgumentNullException("data"); } return SKTypeface.GetObject(SkiaApi.sk_fontmgr_create_from_data(Handle, data.Handle, index)); } public SKTypeface MatchCharacter(char character) { return MatchCharacter(null, SKFontStyle.Normal, null, character); } public SKTypeface MatchCharacter(int character) { return MatchCharacter(null, SKFontStyle.Normal, null, character); } public SKTypeface MatchCharacter(string familyName, char character) { return MatchCharacter(familyName, SKFontStyle.Normal, null, character); } public SKTypeface MatchCharacter(string familyName, int character) { return MatchCharacter(familyName, SKFontStyle.Normal, null, character); } public SKTypeface MatchCharacter(string familyName, string[] bcp47, char character) { return MatchCharacter(familyName, SKFontStyle.Normal, bcp47, character); } public SKTypeface MatchCharacter(string familyName, string[] bcp47, int character) { return MatchCharacter(familyName, SKFontStyle.Normal, bcp47, character); } public SKTypeface MatchCharacter(string familyName, SKFontStyleWeight weight, SKFontStyleWidth width, SKFontStyleSlant slant, string[] bcp47, char character) { return MatchCharacter(familyName, new SKFontStyle(weight, width, slant), bcp47, character); } public SKTypeface MatchCharacter(string familyName, SKFontStyleWeight weight, SKFontStyleWidth width, SKFontStyleSlant slant, string[] bcp47, int character) { return MatchCharacter(familyName, new SKFontStyle(weight, width, slant), bcp47, character); } public SKTypeface MatchCharacter(string familyName, int weight, int width, SKFontStyleSlant slant, string[] bcp47, int character) { return MatchCharacter(familyName, new SKFontStyle(weight, width, slant), bcp47, character); } public unsafe SKTypeface MatchCharacter(string familyName, SKFontStyle style, string[] bcp47, int character) { if (style == null) { throw new ArgumentNullException("style"); } if (familyName == null) { familyName = string.Empty; } fixed (byte* encodedText = StringUtilities.GetEncodedText(familyName, SKTextEncoding.Utf8, addNull: true)) { SKTypeface sKTypeface = SKTypeface.GetObject(SkiaApi.sk_fontmgr_match_family_style_character(Handle, new IntPtr(encodedText), style.Handle, bcp47, (bcp47 != null) ? bcp47.Length : 0, character)); sKTypeface?.PreventPublicDisposal(); return sKTypeface; } } public static SKFontManager CreateDefault() { return GetObject(SkiaApi.sk_fontmgr_create_default()); } internal static SKFontManager GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKFontManager(h, o)); } } public class SKFontStyle : SKObject, ISKSkipObjectRegistration { private sealed class SKFontStyleStatic : SKFontStyle { internal SKFontStyleStatic(SKFontStyleWeight weight, SKFontStyleWidth width, SKFontStyleSlant slant) : base(weight, width, slant) { } protected override void Dispose(bool disposing) { } } private static readonly SKFontStyle normal; private static readonly SKFontStyle bold; private static readonly SKFontStyle italic; private static readonly SKFontStyle boldItalic; public int Weight => SkiaApi.sk_fontstyle_get_weight(Handle); public int Width => SkiaApi.sk_fontstyle_get_width(Handle); public SKFontStyleSlant Slant => SkiaApi.sk_fontstyle_get_slant(Handle); public static SKFontStyle Normal => normal; public static SKFontStyle Bold => bold; public static SKFontStyle Italic => italic; public static SKFontStyle BoldItalic => boldItalic; static SKFontStyle() { normal = new SKFontStyleStatic(SKFontStyleWeight.Normal, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); bold = new SKFontStyleStatic(SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); italic = new SKFontStyleStatic(SKFontStyleWeight.Normal, SKFontStyleWidth.Normal, SKFontStyleSlant.Italic); boldItalic = new SKFontStyleStatic(SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Italic); } internal SKFontStyle(IntPtr handle, bool owns) : base(handle, owns) { } public SKFontStyle() : this(SKFontStyleWeight.Normal, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright) { } public SKFontStyle(SKFontStyleWeight weight, SKFontStyleWidth width, SKFontStyleSlant slant) : this((int)weight, (int)width, slant) { } public SKFontStyle(int weight, int width, SKFontStyleSlant slant) : this(SkiaApi.sk_fontstyle_new(weight, width, slant), owns: true) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_fontstyle_delete(Handle); } internal static SKFontStyle GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new SKFontStyle(handle, owns: true); } return null; } } public class SKFontStyleSet : SKObject, ISKReferenceCounted, IEnumerable, IEnumerable, IReadOnlyCollection, IReadOnlyList { public int Count => SkiaApi.sk_fontstyleset_get_count(Handle); public SKFontStyle this[int index] => GetStyle(index); internal SKFontStyleSet(IntPtr handle, bool owns) : base(handle, owns) { } public SKFontStyleSet() : this(SkiaApi.sk_fontstyleset_create_empty(), owns: true) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public string GetStyleName(int index) { using SKString sKString = new SKString(); SkiaApi.sk_fontstyleset_get_style(Handle, index, IntPtr.Zero, sKString.Handle); GC.KeepAlive(this); return (string)sKString; } public SKTypeface CreateTypeface(int index) { if (index < 0 || index >= Count) { throw new ArgumentOutOfRangeException("Index was out of range. Must be non-negative and less than the size of the set.", "index"); } SKTypeface sKTypeface = SKTypeface.GetObject(SkiaApi.sk_fontstyleset_create_typeface(Handle, index)); sKTypeface?.PreventPublicDisposal(); GC.KeepAlive(this); return sKTypeface; } public SKTypeface CreateTypeface(SKFontStyle style) { if (style == null) { throw new ArgumentNullException("style"); } SKTypeface sKTypeface = SKTypeface.GetObject(SkiaApi.sk_fontstyleset_match_style(Handle, style.Handle)); sKTypeface?.PreventPublicDisposal(); GC.KeepAlive(this); return sKTypeface; } public IEnumerator GetEnumerator() { return GetStyles().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetStyles().GetEnumerator(); } private IEnumerable GetStyles() { int count = Count; for (int i = 0; i < count; i++) { yield return GetStyle(i); } } private SKFontStyle GetStyle(int index) { SKFontStyle sKFontStyle = new SKFontStyle(); SkiaApi.sk_fontstyleset_get_style(Handle, index, sKFontStyle.Handle, IntPtr.Zero); return sKFontStyle; } internal static SKFontStyleSet GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKFontStyleSet(h, o)); } } public class SKFrontBufferedManagedStream : SKAbstractManagedStream { private SKStream stream; private bool disposeStream; private readonly bool hasLength; private readonly int streamLength; private readonly int bufferLength; private byte[] frontBuffer; private int bufferedSoFar; private int offset; public SKFrontBufferedManagedStream(Stream managedStream, int bufferSize) : this(managedStream, bufferSize, disposeUnderlyingStream: false) { } public SKFrontBufferedManagedStream(Stream managedStream, int bufferSize, bool disposeUnderlyingStream) : this(new SKManagedStream(managedStream, disposeUnderlyingStream), bufferSize, disposeUnderlyingStream: true) { } public SKFrontBufferedManagedStream(SKStream nativeStream, int bufferSize) : this(nativeStream, bufferSize, disposeUnderlyingStream: false) { } public SKFrontBufferedManagedStream(SKStream nativeStream, int bufferSize, bool disposeUnderlyingStream) { int num = (nativeStream.HasLength ? nativeStream.Length : 0); int num2 = (nativeStream.HasPosition ? nativeStream.Position : 0); disposeStream = disposeUnderlyingStream; stream = nativeStream; hasLength = nativeStream.HasPosition && nativeStream.HasLength; streamLength = num - num2; offset = 0; bufferedSoFar = 0; bufferLength = bufferSize; frontBuffer = new byte[bufferSize]; } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeManaged() { if (disposeStream && stream != null) { stream.Dispose(); stream = null; } base.DisposeManaged(); } protected override IntPtr OnRead(IntPtr buffer, IntPtr size) { int num = offset; if ((int)size > 0 && offset < bufferedSoFar) { int num2 = Math.Min((int)size, bufferedSoFar - offset); if (buffer != IntPtr.Zero) { Marshal.Copy(frontBuffer, offset, buffer, num2); buffer += num2; } offset += num2; size -= num2; } bool flag = false; if ((int)size > 0 && bufferedSoFar < bufferLength) { int num3 = Math.Min((int)size, bufferLength - bufferedSoFar); IntPtr intPtr = Marshal.AllocCoTaskMem(num3); int num4 = stream.Read(intPtr, num3); Marshal.Copy(intPtr, frontBuffer, offset, num4); Marshal.FreeCoTaskMem(intPtr); flag = num4 < num3; bufferedSoFar += num4; if (buffer != IntPtr.Zero) { Marshal.Copy(frontBuffer, offset, buffer, num4); buffer += num4; } offset += num4; size -= num4; } if ((int)size > 0 && !flag) { int num5 = stream.Read(buffer, (int)size); if (num5 > 0) { frontBuffer = null; } offset += num5; size -= num5; } return (IntPtr)(offset - num); } protected override IntPtr OnPeek(IntPtr buffer, IntPtr size) { if (offset >= bufferLength) { return (IntPtr)0; } int num = offset; int size2 = Math.Min((int)size, bufferLength - offset); int num2 = Read(buffer, size2); offset = num; return (IntPtr)num2; } protected override bool OnIsAtEnd() { if (offset < bufferedSoFar) { return false; } return stream.IsAtEnd; } protected override bool OnRewind() { if (offset <= bufferLength) { offset = 0; return true; } return false; } protected override bool OnHasLength() { return hasLength; } protected override IntPtr OnGetLength() { return (IntPtr)streamLength; } protected override bool OnHasPosition() { return false; } protected override IntPtr OnGetPosition() { return (IntPtr)0; } protected override bool OnSeek(IntPtr position) { return false; } protected override bool OnMove(int offset) { return false; } protected override IntPtr OnCreateNew() { return IntPtr.Zero; } } public class SKFrontBufferedStream : Stream { public const int DefaultBufferSize = 4096; private readonly long totalBufferSize; private readonly long totalLength; private readonly bool disposeStream; private Stream underlyingStream; private long currentOffset; private long bufferedSoFar; private byte[] internalBuffer; public override bool CanRead => true; public override bool CanSeek => true; public override bool CanWrite => false; public override long Length => totalLength; public override long Position { get { return currentOffset; } set { Seek(value, SeekOrigin.Begin); } } public SKFrontBufferedStream(Stream stream) : this(stream, 4096L, disposeUnderlyingStream: false) { } public SKFrontBufferedStream(Stream stream, long bufferSize) : this(stream, bufferSize, disposeUnderlyingStream: false) { } public SKFrontBufferedStream(Stream stream, bool disposeUnderlyingStream) : this(stream, 4096L, disposeUnderlyingStream) { } public SKFrontBufferedStream(Stream stream, long bufferSize, bool disposeUnderlyingStream) { underlyingStream = stream; totalBufferSize = bufferSize; totalLength = (stream.CanSeek ? stream.Length : (-1)); disposeStream = disposeUnderlyingStream; } public override void Flush() { } public override int Read(byte[] buffer, int offset, int count) { long num = currentOffset; if (internalBuffer == null && currentOffset < totalBufferSize) { internalBuffer = new byte[totalBufferSize]; } if (currentOffset < bufferedSoFar) { int num2 = ReadFromBuffer(buffer, offset, count); count -= num2; offset += num2; } if (count > 0 && bufferedSoFar < totalBufferSize) { int num3 = BufferAndWriteTo(buffer, offset, count); count -= num3; offset += num3; } if (count > 0) { int num4 = ReadDirectlyFromStream(buffer, offset, count); count -= num4; offset += num4; if (num4 > 0) { internalBuffer = null; } } return (int)(currentOffset - num); } public override long Seek(long offset, SeekOrigin origin) { if (currentOffset > totalBufferSize) { throw new InvalidOperationException("The position cannot be changed once the stream has moved past the buffer."); } long num = offset; switch (origin) { case SeekOrigin.Current: num = Position + offset; break; case SeekOrigin.End: if (Length == -1) { throw new InvalidOperationException("Can't seek from end as the underlying stream is not seekable."); } num = Length + offset; break; } if (num <= currentOffset) { currentOffset = num; } else { long num2 = num - currentOffset; currentOffset += Read(null, 0, (int)num2); } return Position; } public override void SetLength(long value) { } public override void Write(byte[] buffer, int offset, int count) { } private int ReadFromBuffer(byte[] dst, int offset, int size) { int num = Math.Min(size, (int)(bufferedSoFar - currentOffset)); if (dst != null && offset < dst.Length) { Buffer.BlockCopy(internalBuffer, (int)currentOffset, dst, offset, num); } currentOffset += num; return num; } private int BufferAndWriteTo(byte[] dst, int offset, int size) { int count = Math.Min(size, (int)(totalBufferSize - bufferedSoFar)); int num = underlyingStream.Read(internalBuffer, (int)currentOffset, count); if (dst != null && offset < dst.Length) { Buffer.BlockCopy(internalBuffer, (int)currentOffset, dst, offset, num); } bufferedSoFar += num; currentOffset = bufferedSoFar; return num; } private int ReadDirectlyFromStream(byte[] dst, int offset, int size) { long num = 0L; num = ((dst != null) ? underlyingStream.Read(dst, offset, size) : underlyingStream.Seek(size, SeekOrigin.Current)); currentOffset += num; return (int)num; } protected override void Dispose(bool disposing) { base.Dispose(disposing); internalBuffer = null; if (disposeStream && underlyingStream != null) { underlyingStream.Dispose(); } underlyingStream = null; } } public static class SKGraphics { public static void Init() { SkiaApi.sk_graphics_init(); } public static void PurgeFontCache() { SkiaApi.sk_graphics_purge_font_cache(); } public static void PurgeResourceCache() { SkiaApi.sk_graphics_purge_resource_cache(); } public static void PurgeAllCaches() { SkiaApi.sk_graphics_purge_all_caches(); } public static long GetFontCacheUsed() { return (long)SkiaApi.sk_graphics_get_font_cache_used(); } public static long GetFontCacheLimit() { return (long)SkiaApi.sk_graphics_get_font_cache_limit(); } public static long SetFontCacheLimit(long bytes) { return (long)SkiaApi.sk_graphics_set_font_cache_limit((IntPtr)bytes); } public static int GetFontCacheCountUsed() { return SkiaApi.sk_graphics_get_font_cache_count_used(); } public static int GetFontCacheCountLimit() { return SkiaApi.sk_graphics_get_font_cache_count_limit(); } public static int SetFontCacheCountLimit(int count) { return SkiaApi.sk_graphics_set_font_cache_count_limit(count); } public static int GetFontCachePointSizeLimit() { return SkiaApi.sk_graphics_get_font_cache_point_size_limit(); } public static int SetFontCachePointSizeLimit(int count) { return SkiaApi.sk_graphics_set_font_cache_point_size_limit(count); } public static long GetResourceCacheTotalBytesUsed() { return (long)SkiaApi.sk_graphics_get_resource_cache_total_bytes_used(); } public static long GetResourceCacheTotalByteLimit() { return (long)SkiaApi.sk_graphics_get_resource_cache_total_byte_limit(); } public static long SetResourceCacheTotalByteLimit(long bytes) { return (long)SkiaApi.sk_graphics_set_resource_cache_total_byte_limit((IntPtr)bytes); } public static long GetResourceCacheSingleAllocationByteLimit() { return (long)SkiaApi.sk_graphics_get_resource_cache_single_allocation_byte_limit(); } public static long SetResourceCacheSingleAllocationByteLimit(long bytes) { return (long)SkiaApi.sk_graphics_set_resource_cache_single_allocation_byte_limit((IntPtr)bytes); } public static void DumpMemoryStatistics(SKTraceMemoryDump dump) { if (dump == null) { throw new ArgumentNullException("dump"); } SkiaApi.sk_graphics_dump_memory_statistics(dump.Handle); } } internal class SkiaApi { private const string SKIA = "libSkiaSharp"; [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_backendrendertarget_delete(IntPtr rendertarget); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern GRBackendNative gr_backendrendertarget_get_backend(IntPtr rendertarget); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool gr_backendrendertarget_get_gl_framebufferinfo(IntPtr rendertarget, GRGlFramebufferInfo* glInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int gr_backendrendertarget_get_height(IntPtr rendertarget); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int gr_backendrendertarget_get_samples(IntPtr rendertarget); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int gr_backendrendertarget_get_stencils(IntPtr rendertarget); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int gr_backendrendertarget_get_width(IntPtr rendertarget); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool gr_backendrendertarget_is_valid(IntPtr rendertarget); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_backendrendertarget_new_gl(int width, int height, int samples, int stencils, GRGlFramebufferInfo* glInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_backendrendertarget_new_metal(int width, int height, int samples, GRMtlTextureInfoNative* mtlInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_backendrendertarget_new_vulkan(int width, int height, int samples, GRVkImageInfo* vkImageInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_backendtexture_delete(IntPtr texture); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern GRBackendNative gr_backendtexture_get_backend(IntPtr texture); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool gr_backendtexture_get_gl_textureinfo(IntPtr texture, GRGlTextureInfo* glInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int gr_backendtexture_get_height(IntPtr texture); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int gr_backendtexture_get_width(IntPtr texture); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool gr_backendtexture_has_mipmaps(IntPtr texture); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool gr_backendtexture_is_valid(IntPtr texture); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_backendtexture_new_gl(int width, int height, [MarshalAs(UnmanagedType.I1)] bool mipmapped, GRGlTextureInfo* glInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_backendtexture_new_metal(int width, int height, [MarshalAs(UnmanagedType.I1)] bool mipmapped, GRMtlTextureInfoNative* mtlInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_backendtexture_new_vulkan(int width, int height, GRVkImageInfo* vkInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_abandon_context(IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_dump_memory_statistics(IntPtr context, IntPtr dump); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_flush(IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_flush_and_submit(IntPtr context, [MarshalAs(UnmanagedType.I1)] bool syncCpu); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_free_gpu_resources(IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gr_direct_context_get_resource_cache_limit(IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void gr_direct_context_get_resource_cache_usage(IntPtr context, int* maxResources, IntPtr* maxResourceBytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool gr_direct_context_is_abandoned(IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gr_direct_context_make_gl(IntPtr glInterface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_direct_context_make_gl_with_options(IntPtr glInterface, GRContextOptionsNative* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_direct_context_make_metal(void* device, void* queue); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_direct_context_make_metal_with_options(void* device, void* queue, GRContextOptionsNative* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gr_direct_context_make_vulkan(GRVkBackendContextNative vkBackendContext); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_direct_context_make_vulkan_with_options(GRVkBackendContextNative vkBackendContext, GRContextOptionsNative* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_perform_deferred_cleanup(IntPtr context, long ms); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_purge_unlocked_resources(IntPtr context, [MarshalAs(UnmanagedType.I1)] bool scratchResourcesOnly); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_purge_unlocked_resources_bytes(IntPtr context, IntPtr bytesToPurge, [MarshalAs(UnmanagedType.I1)] bool preferScratchResources); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_release_resources_and_abandon_context(IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_reset_context(IntPtr context, uint state); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_direct_context_set_resource_cache_limit(IntPtr context, IntPtr maxResourceBytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool gr_direct_context_submit(IntPtr context, [MarshalAs(UnmanagedType.I1)] bool syncCpu); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_glinterface_assemble_gl_interface(void* ctx, GRGlGetProcProxyDelegate get); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_glinterface_assemble_gles_interface(void* ctx, GRGlGetProcProxyDelegate get); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_glinterface_assemble_interface(void* ctx, GRGlGetProcProxyDelegate get); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr gr_glinterface_assemble_webgl_interface(void* ctx, GRGlGetProcProxyDelegate get); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gr_glinterface_create_native_interface(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool gr_glinterface_has_extension(IntPtr glInterface, [MarshalAs(UnmanagedType.LPStr)] string extension); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_glinterface_unref(IntPtr glInterface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool gr_glinterface_validate(IntPtr glInterface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern GRBackendNative gr_recording_context_get_backend(IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int gr_recording_context_get_max_surface_sample_count_for_color_type(IntPtr context, SKColorTypeNative colorType); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_recording_context_unref(IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void gr_vk_extensions_delete(IntPtr extensions); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool gr_vk_extensions_has_extension(IntPtr extensions, [MarshalAs(UnmanagedType.LPStr)] string ext, uint minVersion); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void gr_vk_extensions_init(IntPtr extensions, GRVkGetProcProxyDelegate getProc, void* userData, IntPtr instance, IntPtr physDev, uint instanceExtensionCount, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] instanceExtensions, uint deviceExtensionCount, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] deviceExtensions); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gr_vk_extensions_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_bitmap_destructor(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_bitmap_erase(IntPtr cbitmap, uint color); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_bitmap_erase_rect(IntPtr cbitmap, uint color, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_bitmap_extract_alpha(IntPtr cbitmap, IntPtr dst, IntPtr paint, SKPointI* offset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_bitmap_extract_subset(IntPtr cbitmap, IntPtr dst, SKRectI* subset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_bitmap_get_addr(IntPtr cbitmap, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern ushort* sk_bitmap_get_addr_16(IntPtr cbitmap, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern uint* sk_bitmap_get_addr_32(IntPtr cbitmap, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern byte* sk_bitmap_get_addr_8(IntPtr cbitmap, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_bitmap_get_byte_count(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_bitmap_get_info(IntPtr cbitmap, SKImageInfoNative* info); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_bitmap_get_pixel_color(IntPtr cbitmap, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_bitmap_get_pixel_colors(IntPtr cbitmap, uint* colors); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_bitmap_get_pixels(IntPtr cbitmap, IntPtr* length); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_bitmap_get_row_bytes(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_bitmap_install_mask_pixels(IntPtr cbitmap, SKMask* cmask); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_bitmap_install_pixels(IntPtr cbitmap, SKImageInfoNative* cinfo, void* pixels, IntPtr rowBytes, SKBitmapReleaseProxyDelegate releaseProc, void* context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_bitmap_install_pixels_with_pixmap(IntPtr cbitmap, IntPtr cpixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_bitmap_is_immutable(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_bitmap_is_null(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_bitmap_make_shader(IntPtr cbitmap, SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix* cmatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_bitmap_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_bitmap_notify_pixels_changed(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_bitmap_peek_pixels(IntPtr cbitmap, IntPtr cpixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_bitmap_ready_to_draw(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_bitmap_reset(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_bitmap_set_immutable(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_bitmap_set_pixels(IntPtr cbitmap, void* pixels); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_bitmap_swap(IntPtr cbitmap, IntPtr cother); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_bitmap_try_alloc_pixels(IntPtr cbitmap, SKImageInfoNative* requestedInfo, IntPtr rowBytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_bitmap_try_alloc_pixels_with_flags(IntPtr cbitmap, SKImageInfoNative* requestedInfo, uint flags); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_clear(IntPtr param0, uint param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_clear_color4f(IntPtr param0, SKColorF param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_clip_path_with_operation(IntPtr t, IntPtr crect, SKClipOperation op, [MarshalAs(UnmanagedType.I1)] bool doAA); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_clip_rect_with_operation(IntPtr t, SKRect* crect, SKClipOperation op, [MarshalAs(UnmanagedType.I1)] bool doAA); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_clip_region(IntPtr canvas, IntPtr region, SKClipOperation op); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_clip_rrect_with_operation(IntPtr t, IntPtr crect, SKClipOperation op, [MarshalAs(UnmanagedType.I1)] bool doAA); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_concat(IntPtr param0, SKMatrix* param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_destroy(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_discard(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_annotation(IntPtr t, SKRect* rect, void* key, IntPtr value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_arc(IntPtr ccanvas, SKRect* oval, float startAngle, float sweepAngle, [MarshalAs(UnmanagedType.I1)] bool useCenter, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_atlas(IntPtr ccanvas, IntPtr atlas, SKRotationScaleMatrix* xform, SKRect* tex, uint* colors, int count, SKBlendMode mode, SKRect* cullRect, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_circle(IntPtr param0, float cx, float cy, float rad, IntPtr param4); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_color(IntPtr ccanvas, uint color, SKBlendMode mode); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_color4f(IntPtr ccanvas, SKColorF color, SKBlendMode mode); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_drawable(IntPtr param0, IntPtr param1, SKMatrix* param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_drrect(IntPtr ccanvas, IntPtr outer, IntPtr inner, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_image(IntPtr param0, IntPtr param1, float x, float y, IntPtr param4); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_image_lattice(IntPtr t, IntPtr image, SKLatticeInternal* lattice, SKRect* dst, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_image_nine(IntPtr t, IntPtr image, SKRectI* center, SKRect* dst, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_image_rect(IntPtr param0, IntPtr param1, SKRect* src, SKRect* dst, IntPtr param4); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_line(IntPtr ccanvas, float x0, float y0, float x1, float y1, IntPtr cpaint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_link_destination_annotation(IntPtr t, SKRect* rect, IntPtr value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_named_destination_annotation(IntPtr t, SKPoint* point, IntPtr value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_oval(IntPtr param0, SKRect* param1, IntPtr param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_paint(IntPtr param0, IntPtr param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_patch(IntPtr ccanvas, SKPoint* cubics, uint* colors, SKPoint* texCoords, SKBlendMode mode, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_path(IntPtr param0, IntPtr param1, IntPtr param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_picture(IntPtr param0, IntPtr param1, SKMatrix* param2, IntPtr param3); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_point(IntPtr param0, float param1, float param2, IntPtr param3); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_points(IntPtr param0, SKPointMode param1, IntPtr param2, SKPoint* param3, IntPtr param4); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_rect(IntPtr param0, SKRect* param1, IntPtr param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_region(IntPtr param0, IntPtr param1, IntPtr param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_round_rect(IntPtr param0, SKRect* param1, float rx, float ry, IntPtr param4); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_rrect(IntPtr param0, IntPtr param1, IntPtr param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_simple_text(IntPtr ccanvas, void* text, IntPtr byte_length, SKTextEncoding encoding, float x, float y, IntPtr cfont, IntPtr cpaint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_text_blob(IntPtr param0, IntPtr text, float x, float y, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_draw_url_annotation(IntPtr t, SKRect* rect, IntPtr value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_draw_vertices(IntPtr ccanvas, IntPtr vertices, SKBlendMode mode, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_flush(IntPtr ccanvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_canvas_get_device_clip_bounds(IntPtr t, SKRectI* cbounds); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_canvas_get_local_clip_bounds(IntPtr t, SKRect* cbounds); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_canvas_get_save_count(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_get_total_matrix(IntPtr ccanvas, SKMatrix* matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_canvas_is_clip_empty(IntPtr ccanvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_canvas_is_clip_rect(IntPtr ccanvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_canvas_new_from_bitmap(IntPtr bitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_canvas_quick_reject(IntPtr param0, SKRect* param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_reset_matrix(IntPtr ccanvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_restore(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_restore_to_count(IntPtr param0, int saveCount); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_rotate_degrees(IntPtr param0, float degrees); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_rotate_radians(IntPtr param0, float radians); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_canvas_save(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int sk_canvas_save_layer(IntPtr param0, SKRect* param1, IntPtr param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_scale(IntPtr param0, float sx, float sy); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_canvas_set_matrix(IntPtr ccanvas, SKMatrix* matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_skew(IntPtr param0, float sx, float sy); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_canvas_translate(IntPtr param0, float dx, float dy); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_nodraw_canvas_destroy(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_nodraw_canvas_new(int width, int height); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_nway_canvas_add_canvas(IntPtr param0, IntPtr canvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_nway_canvas_destroy(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_nway_canvas_new(int width, int height); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_nway_canvas_remove_all(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_nway_canvas_remove_canvas(IntPtr param0, IntPtr canvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_overdraw_canvas_destroy(IntPtr canvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_overdraw_canvas_new(IntPtr canvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_codec_destroy(IntPtr codec); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKEncodedImageFormat sk_codec_get_encoded_format(IntPtr codec); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_codec_get_frame_count(IntPtr codec); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_codec_get_frame_info(IntPtr codec, SKCodecFrameInfo* frameInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_codec_get_frame_info_for_index(IntPtr codec, int index, SKCodecFrameInfo* frameInfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_codec_get_info(IntPtr codec, SKImageInfoNative* info); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKEncodedOrigin sk_codec_get_origin(IntPtr codec); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern SKCodecResult sk_codec_get_pixels(IntPtr codec, SKImageInfoNative* info, void* pixels, IntPtr rowBytes, SKCodecOptionsInternal* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_codec_get_repetition_count(IntPtr codec); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_codec_get_scaled_dimensions(IntPtr codec, float desiredScale, SKSizeI* dimensions); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKCodecScanlineOrder sk_codec_get_scanline_order(IntPtr codec); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int sk_codec_get_scanlines(IntPtr codec, void* dst, int countLines, IntPtr rowBytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_codec_get_valid_subset(IntPtr codec, SKRectI* desiredSubset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern SKCodecResult sk_codec_incremental_decode(IntPtr codec, int* rowsDecoded); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_codec_min_buffered_bytes_needed(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_codec_new_from_data(IntPtr data); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_codec_new_from_stream(IntPtr stream, SKCodecResult* result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_codec_next_scanline(IntPtr codec); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_codec_output_scanline(IntPtr codec, int inputScanline); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_codec_skip_scanlines(IntPtr codec, int countLines); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern SKCodecResult sk_codec_start_incremental_decode(IntPtr codec, SKImageInfoNative* info, void* pixels, IntPtr rowBytes, SKCodecOptionsInternal* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern SKCodecResult sk_codec_start_scanline_decode(IntPtr codec, SKImageInfoNative* info, SKCodecOptionsInternal* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_colorfilter_new_color_matrix(float* array); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorfilter_new_compose(IntPtr outer, IntPtr inner); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_colorfilter_new_high_contrast(SKHighContrastConfig* config); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorfilter_new_lighting(uint mul, uint add); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorfilter_new_luma_color(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorfilter_new_mode(uint c, SKBlendMode mode); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_colorfilter_new_table(byte* table); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_colorfilter_new_table_argb(byte* tableA, byte* tableR, byte* tableG, byte* tableB); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_colorfilter_unref(IntPtr filter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_color4f_from_color(uint color, SKColorF* color4f); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern uint sk_color4f_to_color(SKColorF* color4f); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_colorspace_equals(IntPtr src, IntPtr dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_colorspace_gamma_close_to_srgb(IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_colorspace_gamma_is_linear(IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_colorspace_icc_profile_delete(IntPtr profile); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern byte* sk_colorspace_icc_profile_get_buffer(IntPtr profile, uint* size); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_colorspace_icc_profile_get_to_xyzd50(IntPtr profile, SKColorSpaceXyz* toXYZD50); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorspace_icc_profile_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_colorspace_icc_profile_parse(void* buffer, IntPtr length, IntPtr profile); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_colorspace_is_numerical_transfer_fn(IntPtr colorspace, SKColorSpaceTransferFn* transferFn); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_colorspace_is_srgb(IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorspace_make_linear_gamma(IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorspace_make_srgb_gamma(IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorspace_new_icc(IntPtr profile); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_colorspace_new_rgb(SKColorSpaceTransferFn* transferFn, SKColorSpaceXyz* toXYZD50); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorspace_new_srgb(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_colorspace_new_srgb_linear(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_colorspace_primaries_to_xyzd50(SKColorSpacePrimaries* primaries, SKColorSpaceXyz* toXYZD50); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_colorspace_ref(IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_colorspace_to_profile(IntPtr colorspace, IntPtr profile); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_colorspace_to_xyzd50(IntPtr colorspace, SKColorSpaceXyz* toXYZD50); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern float sk_colorspace_transfer_fn_eval(SKColorSpaceTransferFn* transferFn, float x); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_colorspace_transfer_fn_invert(SKColorSpaceTransferFn* src, SKColorSpaceTransferFn* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_transfer_fn_named_2dot2(SKColorSpaceTransferFn* transferFn); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_transfer_fn_named_hlg(SKColorSpaceTransferFn* transferFn); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_transfer_fn_named_linear(SKColorSpaceTransferFn* transferFn); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_transfer_fn_named_pq(SKColorSpaceTransferFn* transferFn); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_transfer_fn_named_rec2020(SKColorSpaceTransferFn* transferFn); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_transfer_fn_named_srgb(SKColorSpaceTransferFn* transferFn); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_colorspace_unref(IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_xyz_concat(SKColorSpaceXyz* a, SKColorSpaceXyz* b, SKColorSpaceXyz* result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_colorspace_xyz_invert(SKColorSpaceXyz* src, SKColorSpaceXyz* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_xyz_named_adobe_rgb(SKColorSpaceXyz* xyz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_xyz_named_display_p3(SKColorSpaceXyz* xyz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_xyz_named_rec2020(SKColorSpaceXyz* xyz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_xyz_named_srgb(SKColorSpaceXyz* xyz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colorspace_xyz_named_xyz(SKColorSpaceXyz* xyz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_colortable_count(IntPtr ctable); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_colortable_new(uint* colors, int count); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_colortable_read_colors(IntPtr ctable, uint** colors); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_colortable_unref(IntPtr ctable); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern byte* sk_data_get_bytes(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_data_get_data(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_data_get_size(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_data_new_empty(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_data_new_from_file(void* path); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_data_new_from_stream(IntPtr stream, IntPtr length); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_data_new_subset(IntPtr src, IntPtr offset, IntPtr length); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_data_new_uninitialized(IntPtr size); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_data_new_with_copy(void* src, IntPtr length); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_data_new_with_proc(void* ptr, IntPtr length, SKDataReleaseProxyDelegate proc, void* ctx); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_data_ref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_data_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_document_abort(IntPtr document); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_document_begin_page(IntPtr document, float width, float height, SKRect* content); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_document_close(IntPtr document); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_document_create_pdf_from_stream(IntPtr stream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_document_create_pdf_from_stream_with_metadata(IntPtr stream, SKDocumentPdfMetadataInternal* metadata); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_document_create_xps_from_stream(IntPtr stream, float dpi); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_document_end_page(IntPtr document); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_document_unref(IntPtr document); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_drawable_draw(IntPtr param0, IntPtr param1, SKMatrix* param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_drawable_get_bounds(IntPtr param0, SKRect* param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_drawable_get_generation_id(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_drawable_new_picture_snapshot(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_drawable_notify_drawing_changed(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_drawable_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_font_break_text(IntPtr font, void* text, IntPtr byteLength, SKTextEncoding encoding, float maxWidth, float* measuredWidth, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_delete(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKFontEdging sk_font_get_edging(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKFontHinting sk_font_get_hinting(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern float sk_font_get_metrics(IntPtr font, SKFontMetrics* metrics); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_font_get_path(IntPtr font, ushort glyph, IntPtr path); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_font_get_paths(IntPtr font, ushort* glyphs, int count, SKGlyphPathProxyDelegate glyphPathProc, void* context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_font_get_pos(IntPtr font, ushort* glyphs, int count, SKPoint* pos, SKPoint* origin); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_font_get_scale_x(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_font_get_size(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_font_get_skew_x(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_font_get_typeface(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_font_get_widths_bounds(IntPtr font, ushort* glyphs, int count, float* widths, SKRect* bounds, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_font_get_xpos(IntPtr font, ushort* glyphs, int count, float* xpos, float origin); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_font_is_baseline_snap(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_font_is_embedded_bitmaps(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_font_is_embolden(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_font_is_force_auto_hinting(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_font_is_linear_metrics(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_font_is_subpixel(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern float sk_font_measure_text(IntPtr font, void* text, IntPtr byteLength, SKTextEncoding encoding, SKRect* bounds, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_font_measure_text_no_return(IntPtr font, void* text, IntPtr byteLength, SKTextEncoding encoding, SKRect* bounds, IntPtr paint, float* measuredWidth); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_font_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_font_new_with_values(IntPtr typeface, float size, float scaleX, float skewX); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_baseline_snap(IntPtr font, [MarshalAs(UnmanagedType.I1)] bool value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_edging(IntPtr font, SKFontEdging value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_embedded_bitmaps(IntPtr font, [MarshalAs(UnmanagedType.I1)] bool value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_embolden(IntPtr font, [MarshalAs(UnmanagedType.I1)] bool value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_force_auto_hinting(IntPtr font, [MarshalAs(UnmanagedType.I1)] bool value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_hinting(IntPtr font, SKFontHinting value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_linear_metrics(IntPtr font, [MarshalAs(UnmanagedType.I1)] bool value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_scale_x(IntPtr font, float value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_size(IntPtr font, float value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_skew_x(IntPtr font, float value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_subpixel(IntPtr font, [MarshalAs(UnmanagedType.I1)] bool value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_font_set_typeface(IntPtr font, IntPtr value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int sk_font_text_to_glyphs(IntPtr font, void* text, IntPtr byteLength, SKTextEncoding encoding, ushort* glyphs, int maxGlyphCount); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern ushort sk_font_unichar_to_glyph(IntPtr font, int uni); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_font_unichars_to_glyphs(IntPtr font, int* uni, int count, ushort* glyphs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_text_utils_get_path(void* text, IntPtr length, SKTextEncoding encoding, float x, float y, IntPtr font, IntPtr path); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_text_utils_get_pos_path(void* text, IntPtr length, SKTextEncoding encoding, SKPoint* pos, IntPtr font, IntPtr path); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKColorTypeNative sk_colortype_get_default_8888(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_nvrefcnt_get_ref_count(IntPtr refcnt); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_nvrefcnt_safe_ref(IntPtr refcnt); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_nvrefcnt_safe_unref(IntPtr refcnt); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_nvrefcnt_unique(IntPtr refcnt); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_refcnt_get_ref_count(IntPtr refcnt); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_refcnt_safe_ref(IntPtr refcnt); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_refcnt_safe_unref(IntPtr refcnt); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_refcnt_unique(IntPtr refcnt); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_version_get_increment(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_version_get_milestone(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_version_get_string(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_graphics_dump_memory_statistics(IntPtr dump); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_graphics_get_font_cache_count_limit(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_graphics_get_font_cache_count_used(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_graphics_get_font_cache_limit(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_graphics_get_font_cache_point_size_limit(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_graphics_get_font_cache_used(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_graphics_get_resource_cache_single_allocation_byte_limit(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_graphics_get_resource_cache_total_byte_limit(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_graphics_get_resource_cache_total_bytes_used(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_graphics_init(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_graphics_purge_all_caches(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_graphics_purge_font_cache(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_graphics_purge_resource_cache(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_graphics_set_font_cache_count_limit(int count); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_graphics_set_font_cache_limit(IntPtr bytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_graphics_set_font_cache_point_size_limit(int maxPointSize); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_graphics_set_resource_cache_single_allocation_byte_limit(IntPtr newLimit); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_graphics_set_resource_cache_total_byte_limit(IntPtr newLimit); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_encode(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_encode_specific(IntPtr cimage, SKEncodedImageFormat encoder, int quality); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKAlphaType sk_image_get_alpha_type(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKColorTypeNative sk_image_get_color_type(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_get_colorspace(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_image_get_height(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_image_get_unique_id(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_image_get_width(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_image_is_alpha_only(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_image_is_lazy_generated(IntPtr image); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_image_is_texture_backed(IntPtr image); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_image_is_valid(IntPtr image, IntPtr context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_make_non_texture_image(IntPtr cimage); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_make_raster_image(IntPtr cimage); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_make_shader(IntPtr param0, SKShaderTileMode tileX, SKShaderTileMode tileY, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_make_subset(IntPtr cimage, SKRectI* subset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_make_texture_image(IntPtr cimage, IntPtr context, [MarshalAs(UnmanagedType.I1)] bool mipmapped); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_make_with_filter(IntPtr cimage, IntPtr context, IntPtr filter, SKRectI* subset, SKRectI* clipBounds, SKRectI* outSubset, SKPointI* outOffset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_make_with_filter_legacy(IntPtr cimage, IntPtr filter, SKRectI* subset, SKRectI* clipBounds, SKRectI* outSubset, SKPointI* outOffset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_new_from_adopted_texture(IntPtr context, IntPtr texture, GRSurfaceOrigin origin, SKColorTypeNative colorType, SKAlphaType alpha, IntPtr colorSpace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_new_from_bitmap(IntPtr cbitmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_new_from_encoded(IntPtr encoded); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_new_from_picture(IntPtr picture, SKSizeI* dimensions, SKMatrix* matrix, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_new_from_texture(IntPtr context, IntPtr texture, GRSurfaceOrigin origin, SKColorTypeNative colorType, SKAlphaType alpha, IntPtr colorSpace, SKImageTextureReleaseProxyDelegate releaseProc, void* releaseContext); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_new_raster(IntPtr pixmap, SKImageRasterReleaseProxyDelegate releaseProc, void* context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_new_raster_copy(SKImageInfoNative* param0, void* pixels, IntPtr rowBytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_new_raster_copy_with_pixmap(IntPtr pixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_image_new_raster_data(SKImageInfoNative* cinfo, IntPtr pixels, IntPtr rowBytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_image_peek_pixels(IntPtr image, IntPtr pixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_image_read_pixels(IntPtr image, SKImageInfoNative* dstInfo, void* dstPixels, IntPtr dstRowBytes, int srcX, int srcY, SKImageCachingHint cachingHint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_image_read_pixels_into_pixmap(IntPtr image, IntPtr dst, int srcX, int srcY, SKImageCachingHint cachingHint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_image_ref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_image_ref_encoded(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_image_scale_pixels(IntPtr image, IntPtr dst, SKFilterQuality quality, SKImageCachingHint cachingHint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_image_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_imagefilter_croprect_destructor(IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_imagefilter_croprect_get_flags(IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_imagefilter_croprect_get_rect(IntPtr cropRect, SKRect* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_croprect_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_croprect_new_with_rect(SKRect* rect, uint flags); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_alpha_threshold(IntPtr region, float innerThreshold, float outerThreshold, IntPtr input); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_arithmetic(float k1, float k2, float k3, float k4, [MarshalAs(UnmanagedType.I1)] bool enforcePMColor, IntPtr background, IntPtr foreground, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_blur(float sigmaX, float sigmaY, SKShaderTileMode tileMode, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_color_filter(IntPtr cf, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_compose(IntPtr outer, IntPtr inner); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_dilate(float radiusX, float radiusY, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_displacement_map_effect(SKColorChannel xChannelSelector, SKColorChannel yChannelSelector, float scale, IntPtr displacement, IntPtr color, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_distant_lit_diffuse(SKPoint3* direction, uint lightColor, float surfaceScale, float kd, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_distant_lit_specular(SKPoint3* direction, uint lightColor, float surfaceScale, float ks, float shininess, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_drop_shadow(float dx, float dy, float sigmaX, float sigmaY, uint color, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_drop_shadow_only(float dx, float dy, float sigmaX, float sigmaY, uint color, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_erode(float radiusX, float radiusY, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_image_source(IntPtr image, SKRect* srcRect, SKRect* dstRect, SKFilterQuality filterQuality); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_image_source_default(IntPtr image); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_magnifier(SKRect* src, float inset, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_matrix(SKMatrix* matrix, SKFilterQuality quality, IntPtr input); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_matrix_convolution(SKSizeI* kernelSize, float* kernel, float gain, float bias, SKPointI* kernelOffset, SKShaderTileMode tileMode, [MarshalAs(UnmanagedType.I1)] bool convolveAlpha, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_merge(IntPtr* filters, int count, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_offset(float dx, float dy, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_paint(IntPtr paint, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_picture(IntPtr picture); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_picture_with_croprect(IntPtr picture, SKRect* cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_point_lit_diffuse(SKPoint3* location, uint lightColor, float surfaceScale, float kd, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_point_lit_specular(SKPoint3* location, uint lightColor, float surfaceScale, float ks, float shininess, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_spot_lit_diffuse(SKPoint3* location, SKPoint3* target, float specularExponent, float cutoffAngle, uint lightColor, float surfaceScale, float kd, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_spot_lit_specular(SKPoint3* location, SKPoint3* target, float specularExponent, float cutoffAngle, uint lightColor, float surfaceScale, float ks, float shininess, IntPtr input, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_imagefilter_new_tile(SKRect* src, SKRect* dst, IntPtr input); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_imagefilter_new_xfermode(SKBlendMode mode, IntPtr background, IntPtr foreground, IntPtr cropRect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_imagefilter_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern byte* sk_mask_alloc_image(IntPtr bytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_mask_compute_image_size(SKMask* cmask); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_mask_compute_total_image_size(SKMask* cmask); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_mask_free_image(void* image); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_mask_get_addr(SKMask* cmask, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern byte* sk_mask_get_addr_1(SKMask* cmask, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern uint* sk_mask_get_addr_32(SKMask* cmask, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern byte* sk_mask_get_addr_8(SKMask* cmask, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern ushort* sk_mask_get_addr_lcd_16(SKMask* cmask, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_mask_is_empty(SKMask* cmask); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_maskfilter_new_blur(SKBlurStyle param0, float sigma); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_maskfilter_new_blur_with_flags(SKBlurStyle param0, float sigma, [MarshalAs(UnmanagedType.I1)] bool respectCTM); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_maskfilter_new_clip(byte min, byte max); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_maskfilter_new_gamma(float gamma); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_maskfilter_new_shader(IntPtr cshader); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_maskfilter_new_table(byte* table); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_maskfilter_ref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_maskfilter_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_apply_to_canvas(IntPtr cview, IntPtr ccanvas); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_destroy(IntPtr cview); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_3dview_dot_with_normal(IntPtr cview, float dx, float dy, float dz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_3dview_get_matrix(IntPtr cview, SKMatrix* cmatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_3dview_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_restore(IntPtr cview); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_rotate_x_degrees(IntPtr cview, float degrees); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_rotate_x_radians(IntPtr cview, float radians); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_rotate_y_degrees(IntPtr cview, float degrees); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_rotate_y_radians(IntPtr cview, float radians); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_rotate_z_degrees(IntPtr cview, float degrees); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_rotate_z_radians(IntPtr cview, float radians); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_save(IntPtr cview); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_3dview_translate(IntPtr cview, float x, float y, float z); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix_concat(SKMatrix* result, SKMatrix* first, SKMatrix* second); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix_map_points(SKMatrix* matrix, SKPoint* dst, SKPoint* src, int count); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern float sk_matrix_map_radius(SKMatrix* matrix, float radius); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix_map_rect(SKMatrix* matrix, SKRect* dest, SKRect* source); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix_map_vector(SKMatrix* matrix, float x, float y, SKPoint* result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix_map_vectors(SKMatrix* matrix, SKPoint* dst, SKPoint* src, int count); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix_map_xy(SKMatrix* matrix, float x, float y, SKPoint* result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix_post_concat(SKMatrix* result, SKMatrix* matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix_pre_concat(SKMatrix* result, SKMatrix* matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_matrix_try_invert(SKMatrix* matrix, SKMatrix* result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix44_as_col_major(IntPtr matrix, float* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix44_as_row_major(IntPtr matrix, float* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_destroy(IntPtr matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern double sk_matrix44_determinant(IntPtr matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_matrix44_equals(IntPtr matrix, IntPtr other); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_matrix44_get(IntPtr matrix, int row, int col); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKMatrix44TypeMask sk_matrix44_get_type(IntPtr matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_matrix44_invert(IntPtr matrix, IntPtr inverse); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix44_map_scalars(IntPtr matrix, float* src, float* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix44_map2(IntPtr matrix, float* src2, int count, float* dst4); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_matrix44_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_matrix44_new_concat(IntPtr a, IntPtr b); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_matrix44_new_copy(IntPtr src); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_matrix44_new_identity(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_matrix44_new_matrix(SKMatrix* src); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_post_concat(IntPtr matrix, IntPtr m); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_post_scale(IntPtr matrix, float sx, float sy, float sz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_post_translate(IntPtr matrix, float dx, float dy, float dz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_pre_concat(IntPtr matrix, IntPtr m); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_pre_scale(IntPtr matrix, float sx, float sy, float sz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_pre_translate(IntPtr matrix, float dx, float dy, float dz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_matrix44_preserves_2d_axis_alignment(IntPtr matrix, float epsilon); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_set(IntPtr matrix, int row, int col, float value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix44_set_3x3_row_major(IntPtr matrix, float* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix44_set_col_major(IntPtr matrix, float* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_set_concat(IntPtr matrix, IntPtr a, IntPtr b); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_set_identity(IntPtr matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_set_rotate_about_degrees(IntPtr matrix, float x, float y, float z, float degrees); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_set_rotate_about_radians(IntPtr matrix, float x, float y, float z, float radians); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_set_rotate_about_radians_unit(IntPtr matrix, float x, float y, float z, float radians); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix44_set_row_major(IntPtr matrix, float* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_set_scale(IntPtr matrix, float sx, float sy, float sz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_set_translate(IntPtr matrix, float dx, float dy, float dz); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_matrix44_to_matrix(IntPtr matrix, SKMatrix* dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_matrix44_transpose(IntPtr matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_paint_clone(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_delete(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKBlendMode sk_paint_get_blendmode(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_paint_get_color(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_paint_get_color4f(IntPtr paint, SKColorF* color); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_paint_get_colorfilter(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_paint_get_fill_path(IntPtr param0, IntPtr src, IntPtr dst, SKRect* cullRect, float resScale); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKFilterQuality sk_paint_get_filter_quality(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_paint_get_imagefilter(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_paint_get_maskfilter(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_paint_get_path_effect(IntPtr cpaint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_paint_get_shader(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKStrokeCap sk_paint_get_stroke_cap(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKStrokeJoin sk_paint_get_stroke_join(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_paint_get_stroke_miter(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_paint_get_stroke_width(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKPaintStyle sk_paint_get_style(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_paint_is_antialias(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_paint_is_dither(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_paint_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_reset(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_antialias(IntPtr param0, [MarshalAs(UnmanagedType.I1)] bool param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_blendmode(IntPtr param0, SKBlendMode param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_color(IntPtr param0, uint param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_paint_set_color4f(IntPtr paint, SKColorF* color, IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_colorfilter(IntPtr param0, IntPtr param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_dither(IntPtr param0, [MarshalAs(UnmanagedType.I1)] bool param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_filter_quality(IntPtr param0, SKFilterQuality param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_imagefilter(IntPtr param0, IntPtr param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_maskfilter(IntPtr param0, IntPtr param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_path_effect(IntPtr cpaint, IntPtr effect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_shader(IntPtr param0, IntPtr param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_stroke_cap(IntPtr param0, SKStrokeCap param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_stroke_join(IntPtr param0, SKStrokeJoin param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_stroke_miter(IntPtr param0, float miter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_stroke_width(IntPtr param0, float width); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_paint_set_style(IntPtr param0, SKPaintStyle param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_opbuilder_add(IntPtr builder, IntPtr path, SKPathOp op); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_opbuilder_destroy(IntPtr builder); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_opbuilder_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_opbuilder_resolve(IntPtr builder, IntPtr result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_add_arc(IntPtr cpath, SKRect* crect, float startAngle, float sweepAngle); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_add_circle(IntPtr param0, float x, float y, float radius, SKPathDirection dir); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_add_oval(IntPtr param0, SKRect* param1, SKPathDirection param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_add_path(IntPtr cpath, IntPtr other, SKPathAddMode add_mode); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_add_path_matrix(IntPtr cpath, IntPtr other, SKMatrix* matrix, SKPathAddMode add_mode); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_add_path_offset(IntPtr cpath, IntPtr other, float dx, float dy, SKPathAddMode add_mode); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_add_path_reverse(IntPtr cpath, IntPtr other); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_add_poly(IntPtr cpath, SKPoint* points, int count, [MarshalAs(UnmanagedType.I1)] bool close); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_add_rect(IntPtr param0, SKRect* param1, SKPathDirection param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_add_rect_start(IntPtr cpath, SKRect* crect, SKPathDirection cdir, uint startIndex); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_add_rounded_rect(IntPtr param0, SKRect* param1, float param2, float param3, SKPathDirection param4); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_add_rrect(IntPtr param0, IntPtr param1, SKPathDirection param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_add_rrect_start(IntPtr param0, IntPtr param1, SKPathDirection param2, uint param3); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_arc_to(IntPtr param0, float rx, float ry, float xAxisRotate, SKPathArcSize largeArc, SKPathDirection sweep, float x, float y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_arc_to_with_oval(IntPtr param0, SKRect* oval, float startAngle, float sweepAngle, [MarshalAs(UnmanagedType.I1)] bool forceMoveTo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_arc_to_with_points(IntPtr param0, float x1, float y1, float x2, float y2, float radius); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_clone(IntPtr cpath); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_close(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_compute_tight_bounds(IntPtr param0, SKRect* param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_conic_to(IntPtr param0, float x0, float y0, float x1, float y1, float w); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_path_contains(IntPtr cpath, float x, float y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int sk_path_convert_conic_to_quads(SKPoint* p0, SKPoint* p1, SKPoint* p2, float w, SKPoint* pts, int pow2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_path_count_points(IntPtr cpath); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_path_count_verbs(IntPtr cpath); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_create_iter(IntPtr cpath, int forceClose); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_create_rawiter(IntPtr cpath); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_cubic_to(IntPtr param0, float x0, float y0, float x1, float y1, float x2, float y2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_delete(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_get_bounds(IntPtr param0, SKRect* param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKPathFillType sk_path_get_filltype(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_path_get_last_point(IntPtr cpath, SKPoint* point); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_get_point(IntPtr cpath, int index, SKPoint* point); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int sk_path_get_points(IntPtr cpath, SKPoint* points, int max); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_path_get_segment_masks(IntPtr cpath); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_path_is_convex(IntPtr cpath); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_path_is_line(IntPtr cpath, SKPoint* line); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_path_is_oval(IntPtr cpath, SKRect* bounds); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_path_is_rect(IntPtr cpath, SKRect* rect, byte* isClosed, SKPathDirection* direction); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_path_is_rrect(IntPtr cpath, IntPtr bounds); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_path_iter_conic_weight(IntPtr iterator); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_iter_destroy(IntPtr iterator); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_path_iter_is_close_line(IntPtr iterator); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_path_iter_is_closed_contour(IntPtr iterator); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern SKPathVerb sk_path_iter_next(IntPtr iterator, SKPoint* points); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_line_to(IntPtr param0, float x, float y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_move_to(IntPtr param0, float x, float y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_path_parse_svg_string(IntPtr cpath, [MarshalAs(UnmanagedType.LPStr)] string str); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_quad_to(IntPtr param0, float x0, float y0, float x1, float y1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_rarc_to(IntPtr param0, float rx, float ry, float xAxisRotate, SKPathArcSize largeArc, SKPathDirection sweep, float x, float y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_path_rawiter_conic_weight(IntPtr iterator); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_rawiter_destroy(IntPtr iterator); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern SKPathVerb sk_path_rawiter_next(IntPtr iterator, SKPoint* points); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKPathVerb sk_path_rawiter_peek(IntPtr iterator); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_rconic_to(IntPtr param0, float dx0, float dy0, float dx1, float dy1, float w); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_rcubic_to(IntPtr param0, float dx0, float dy0, float dx1, float dy1, float dx2, float dy2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_reset(IntPtr cpath); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_rewind(IntPtr cpath); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_rline_to(IntPtr param0, float dx, float yd); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_rmove_to(IntPtr param0, float dx, float dy); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_rquad_to(IntPtr param0, float dx0, float dy0, float dx1, float dy1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_set_filltype(IntPtr param0, SKPathFillType param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_to_svg_string(IntPtr cpath, IntPtr str); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_transform(IntPtr cpath, SKMatrix* cmatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_path_transform_to_dest(IntPtr cpath, SKMatrix* cmatrix, IntPtr destination); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_pathmeasure_destroy(IntPtr pathMeasure); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_pathmeasure_get_length(IntPtr pathMeasure); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_pathmeasure_get_matrix(IntPtr pathMeasure, float distance, SKMatrix* matrix, SKPathMeasureMatrixFlags flags); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_pathmeasure_get_pos_tan(IntPtr pathMeasure, float distance, SKPoint* position, SKPoint* tangent); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_pathmeasure_get_segment(IntPtr pathMeasure, float start, float stop, IntPtr dst, [MarshalAs(UnmanagedType.I1)] bool startWithMoveTo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_pathmeasure_is_closed(IntPtr pathMeasure); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_pathmeasure_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_pathmeasure_new_with_path(IntPtr path, [MarshalAs(UnmanagedType.I1)] bool forceClosed, float resScale); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_pathmeasure_next_contour(IntPtr pathMeasure); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_pathmeasure_set_path(IntPtr pathMeasure, IntPtr path, [MarshalAs(UnmanagedType.I1)] bool forceClosed); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_pathop_as_winding(IntPtr path, IntPtr result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_pathop_op(IntPtr one, IntPtr two, SKPathOp op, IntPtr result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_pathop_simplify(IntPtr path, IntPtr result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_pathop_tight_bounds(IntPtr path, SKRect* result); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_effect_create_1d_path(IntPtr path, float advance, float phase, SKPath1DPathEffectStyle style); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_path_effect_create_2d_line(float width, SKMatrix* matrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_path_effect_create_2d_path(SKMatrix* matrix, IntPtr path); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_effect_create_compose(IntPtr outer, IntPtr inner); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_effect_create_corner(float radius); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_path_effect_create_dash(float* intervals, int count, float phase); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_effect_create_discrete(float segLength, float deviation, uint seedAssist); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_effect_create_sum(IntPtr first, IntPtr second); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_path_effect_create_trim(float start, float stop, SKTrimPathEffectMode mode); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_path_effect_unref(IntPtr t); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_picture_deserialize_from_data(IntPtr data); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_picture_deserialize_from_memory(void* buffer, IntPtr length); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_picture_deserialize_from_stream(IntPtr stream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_picture_get_cull_rect(IntPtr param0, SKRect* param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_picture_get_recording_canvas(IntPtr crec); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_picture_get_unique_id(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_picture_make_shader(IntPtr src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix* localMatrix, SKRect* tile); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_picture_recorder_begin_recording(IntPtr param0, SKRect* param1); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_picture_recorder_delete(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_picture_recorder_end_recording(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_picture_recorder_end_recording_as_drawable(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_picture_recorder_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_picture_ref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_picture_serialize_to_data(IntPtr picture); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_picture_serialize_to_stream(IntPtr picture, IntPtr stream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_picture_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_color_get_bit_shift(int* a, int* r, int* g, int* b); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_color_premultiply(uint color); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_color_premultiply_array(uint* colors, int size, uint* pmcolors); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_color_unpremultiply(uint pmcolor); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_color_unpremultiply_array(uint* pmcolors, int size, uint* colors); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_jpegencoder_encode(IntPtr dst, IntPtr src, SKJpegEncoderOptions* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_pixmap_destructor(IntPtr cpixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_pixmap_encode_image(IntPtr dst, IntPtr src, SKEncodedImageFormat encoder, int quality); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_pixmap_erase_color(IntPtr cpixmap, uint color, SKRectI* subset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_pixmap_erase_color4f(IntPtr cpixmap, SKColorF* color, IntPtr colorspace, SKRectI* subset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_pixmap_extract_subset(IntPtr cpixmap, IntPtr result, SKRectI* subset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_pixmap_get_info(IntPtr cpixmap, SKImageInfoNative* cinfo); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_pixmap_get_pixel_color(IntPtr cpixmap, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_pixmap_get_pixels(IntPtr cpixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_pixmap_get_pixels_with_xy(IntPtr cpixmap, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_pixmap_get_row_bytes(IntPtr cpixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_pixmap_get_writable_addr(IntPtr cpixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_pixmap_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_pixmap_new_with_params(SKImageInfoNative* cinfo, void* addr, IntPtr rowBytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_pixmap_read_pixels(IntPtr cpixmap, SKImageInfoNative* dstInfo, void* dstPixels, IntPtr dstRowBytes, int srcX, int srcY); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_pixmap_reset(IntPtr cpixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_pixmap_reset_with_params(IntPtr cpixmap, SKImageInfoNative* cinfo, void* addr, IntPtr rowBytes); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_pixmap_scale_pixels(IntPtr cpixmap, IntPtr dst, SKFilterQuality quality); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_pngencoder_encode(IntPtr dst, IntPtr src, SKPngEncoderOptions* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_swizzle_swap_rb(uint* dest, uint* src, int count); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_webpencoder_encode(IntPtr dst, IntPtr src, SKWebpEncoderOptions* options); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_region_cliperator_delete(IntPtr iter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_cliperator_done(IntPtr iter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_region_cliperator_new(IntPtr region, SKRectI* clip); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_region_cliperator_next(IntPtr iter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_region_cliperator_rect(IntPtr iter, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_contains(IntPtr r, IntPtr region); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_contains_point(IntPtr r, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_region_contains_rect(IntPtr r, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_region_delete(IntPtr r); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_get_boundary_path(IntPtr r, IntPtr path); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_region_get_bounds(IntPtr r, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_intersects(IntPtr r, IntPtr src); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_region_intersects_rect(IntPtr r, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_is_complex(IntPtr r); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_is_empty(IntPtr r); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_is_rect(IntPtr r); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_region_iterator_delete(IntPtr iter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_iterator_done(IntPtr iter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_region_iterator_new(IntPtr region); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_region_iterator_next(IntPtr iter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_region_iterator_rect(IntPtr iter, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_iterator_rewind(IntPtr iter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_region_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_op(IntPtr r, IntPtr region, SKRegionOperation op); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_region_op_rect(IntPtr r, SKRectI* rect, SKRegionOperation op); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_region_quick_contains(IntPtr r, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_quick_reject(IntPtr r, IntPtr region); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_region_quick_reject_rect(IntPtr r, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_set_empty(IntPtr r); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_set_path(IntPtr r, IntPtr t, IntPtr clip); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_region_set_rect(IntPtr r, SKRectI* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_region_set_rects(IntPtr r, SKRectI* rects, int count); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_region_set_region(IntPtr r, IntPtr region); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_region_spanerator_delete(IntPtr iter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_region_spanerator_new(IntPtr region, int y, int left, int right); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_region_spanerator_next(IntPtr iter, int* left, int* right); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_region_translate(IntPtr r, int x, int y); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_rrect_contains(IntPtr rrect, SKRect* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_rrect_delete(IntPtr rrect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_rrect_get_height(IntPtr rrect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_rrect_get_radii(IntPtr rrect, SKRoundRectCorner corner, SKPoint* radii); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_rrect_get_rect(IntPtr rrect, SKRect* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKRoundRectType sk_rrect_get_type(IntPtr rrect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern float sk_rrect_get_width(IntPtr rrect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_rrect_inset(IntPtr rrect, float dx, float dy); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_rrect_is_valid(IntPtr rrect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_rrect_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_rrect_new_copy(IntPtr rrect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_rrect_offset(IntPtr rrect, float dx, float dy); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_rrect_outset(IntPtr rrect, float dx, float dy); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_rrect_set_empty(IntPtr rrect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_rrect_set_nine_patch(IntPtr rrect, SKRect* rect, float leftRad, float topRad, float rightRad, float bottomRad); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_rrect_set_oval(IntPtr rrect, SKRect* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_rrect_set_rect(IntPtr rrect, SKRect* rect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_rrect_set_rect_radii(IntPtr rrect, SKRect* rect, SKPoint* radii); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_rrect_set_rect_xy(IntPtr rrect, SKRect* rect, float xRad, float yRad); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_rrect_transform(IntPtr rrect, SKMatrix* matrix, IntPtr dest); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_runtimeeffect_get_child_name(IntPtr effect, int index, IntPtr name); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_runtimeeffect_get_children_count(IntPtr effect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_runtimeeffect_get_uniform_from_index(IntPtr effect, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_runtimeeffect_get_uniform_from_name(IntPtr effect, void* name, IntPtr len); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_runtimeeffect_get_uniform_name(IntPtr effect, int index, IntPtr name); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_runtimeeffect_get_uniform_size(IntPtr effect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_runtimeeffect_get_uniforms_count(IntPtr effect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_runtimeeffect_make(IntPtr sksl, IntPtr error); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_runtimeeffect_make_color_filter(IntPtr effect, IntPtr uniforms, IntPtr* children, IntPtr childCount); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_runtimeeffect_make_shader(IntPtr effect, IntPtr uniforms, IntPtr* children, IntPtr childCount, SKMatrix* localMatrix, [MarshalAs(UnmanagedType.I1)] bool isOpaque); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_runtimeeffect_uniform_get_offset(IntPtr variable); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_runtimeeffect_uniform_get_size_in_bytes(IntPtr variable); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_runtimeeffect_unref(IntPtr effect); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_shader_new_blend(SKBlendMode mode, IntPtr dst, IntPtr src); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_shader_new_color(uint color); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_color4f(SKColorF* color, IntPtr colorspace); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_shader_new_empty(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_shader_new_lerp(float t, IntPtr dst, IntPtr src); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_linear_gradient(SKPoint* points, uint* colors, float* colorPos, int colorCount, SKShaderTileMode tileMode, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_linear_gradient_color4f(SKPoint* points, SKColorF* colors, IntPtr colorspace, float* colorPos, int colorCount, SKShaderTileMode tileMode, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_perlin_noise_fractal_noise(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKSizeI* tileSize); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_shader_new_perlin_noise_improved_noise(float baseFrequencyX, float baseFrequencyY, int numOctaves, float z); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_perlin_noise_turbulence(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKSizeI* tileSize); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_radial_gradient(SKPoint* center, float radius, uint* colors, float* colorPos, int colorCount, SKShaderTileMode tileMode, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_radial_gradient_color4f(SKPoint* center, float radius, SKColorF* colors, IntPtr colorspace, float* colorPos, int colorCount, SKShaderTileMode tileMode, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_sweep_gradient(SKPoint* center, uint* colors, float* colorPos, int colorCount, SKShaderTileMode tileMode, float startAngle, float endAngle, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_sweep_gradient_color4f(SKPoint* center, SKColorF* colors, IntPtr colorspace, float* colorPos, int colorCount, SKShaderTileMode tileMode, float startAngle, float endAngle, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_two_point_conical_gradient(SKPoint* start, float startRadius, SKPoint* end, float endRadius, uint* colors, float* colorPos, int colorCount, SKShaderTileMode tileMode, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_new_two_point_conical_gradient_color4f(SKPoint* start, float startRadius, SKPoint* end, float endRadius, SKColorF* colors, IntPtr colorspace, float* colorPos, int colorCount, SKShaderTileMode tileMode, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_shader_ref(IntPtr shader); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_shader_unref(IntPtr shader); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_shader_with_color_filter(IntPtr shader, IntPtr filter); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_shader_with_local_matrix(IntPtr shader, SKMatrix* localMatrix); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_dynamicmemorywstream_copy_to(IntPtr cstream, void* data); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_dynamicmemorywstream_destroy(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_dynamicmemorywstream_detach_as_data(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_dynamicmemorywstream_detach_as_stream(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_dynamicmemorywstream_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_dynamicmemorywstream_write_to_stream(IntPtr cstream, IntPtr dst); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_filestream_destroy(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_filestream_is_valid(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_filestream_new(void* path); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_filewstream_destroy(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_filewstream_is_valid(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_filewstream_new(void* path); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_memorystream_destroy(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_memorystream_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_memorystream_new_with_data(void* data, IntPtr length, [MarshalAs(UnmanagedType.I1)] bool copyData); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_memorystream_new_with_length(IntPtr length); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_memorystream_new_with_skdata(IntPtr data); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_memorystream_set_memory(IntPtr cmemorystream, void* data, IntPtr length, [MarshalAs(UnmanagedType.I1)] bool copyData); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_stream_asset_destroy(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_stream_destroy(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_stream_duplicate(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_stream_fork(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_stream_get_length(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_stream_get_memory_base(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_stream_get_position(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_stream_has_length(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_stream_has_position(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_stream_is_at_end(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_stream_move(IntPtr cstream, int offset); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_stream_peek(IntPtr cstream, void* buffer, IntPtr size); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_stream_read(IntPtr cstream, void* buffer, IntPtr size); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_stream_read_bool(IntPtr cstream, byte* buffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_stream_read_s16(IntPtr cstream, short* buffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_stream_read_s32(IntPtr cstream, int* buffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_stream_read_s8(IntPtr cstream, sbyte* buffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_stream_read_u16(IntPtr cstream, ushort* buffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_stream_read_u32(IntPtr cstream, uint* buffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_stream_read_u8(IntPtr cstream, byte* buffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_stream_rewind(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_stream_seek(IntPtr cstream, IntPtr position); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_stream_skip(IntPtr cstream, IntPtr size); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_wstream_bytes_written(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_wstream_flush(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_wstream_get_size_of_packed_uint(IntPtr value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_newline(IntPtr cstream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_wstream_write(IntPtr cstream, void* buffer, IntPtr size); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_16(IntPtr cstream, ushort value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_32(IntPtr cstream, uint value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_8(IntPtr cstream, byte value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_bigdec_as_text(IntPtr cstream, long value, int minDigits); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_bool(IntPtr cstream, [MarshalAs(UnmanagedType.I1)] bool value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_dec_as_text(IntPtr cstream, int value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_hex_as_text(IntPtr cstream, uint value, int minDigits); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_packed_uint(IntPtr cstream, IntPtr value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_scalar(IntPtr cstream, float value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_scalar_as_text(IntPtr cstream, float value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_stream(IntPtr cstream, IntPtr input, IntPtr length); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_wstream_write_text(IntPtr cstream, [MarshalAs(UnmanagedType.LPStr)] string value); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_string_destructor(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void* sk_string_get_c_str(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_string_get_size(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_string_new_empty(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_string_new_with_copy(void* src, IntPtr length); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_surface_draw(IntPtr surface, IntPtr canvas, float x, float y, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_surface_flush(IntPtr surface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_surface_flush_and_submit(IntPtr surface, [MarshalAs(UnmanagedType.I1)] bool syncCpu); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_surface_get_canvas(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_surface_get_props(IntPtr surface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_surface_get_recording_context(IntPtr surface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_surface_new_backend_render_target(IntPtr context, IntPtr target, GRSurfaceOrigin origin, SKColorTypeNative colorType, IntPtr colorspace, IntPtr props); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_surface_new_backend_texture(IntPtr context, IntPtr texture, GRSurfaceOrigin origin, int samples, SKColorTypeNative colorType, IntPtr colorspace, IntPtr props); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_surface_new_image_snapshot(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_surface_new_image_snapshot_with_crop(IntPtr surface, SKRectI* bounds); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_surface_new_metal_layer(IntPtr context, void* layer, GRSurfaceOrigin origin, int sampleCount, SKColorTypeNative colorType, IntPtr colorspace, IntPtr props, void** drawable); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_surface_new_metal_view(IntPtr context, void* mtkView, GRSurfaceOrigin origin, int sampleCount, SKColorTypeNative colorType, IntPtr colorspace, IntPtr props); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_surface_new_null(int width, int height); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_surface_new_raster(SKImageInfoNative* param0, IntPtr rowBytes, IntPtr param2); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_surface_new_raster_direct(SKImageInfoNative* param0, void* pixels, IntPtr rowBytes, SKSurfaceRasterReleaseProxyDelegate releaseProc, void* context, IntPtr props); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_surface_new_render_target(IntPtr context, [MarshalAs(UnmanagedType.I1)] bool budgeted, SKImageInfoNative* cinfo, int sampleCount, GRSurfaceOrigin origin, IntPtr props, [MarshalAs(UnmanagedType.I1)] bool shouldCreateWithMips); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_surface_peek_pixels(IntPtr surface, IntPtr pixmap); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_surface_read_pixels(IntPtr surface, SKImageInfoNative* dstInfo, void* dstPixels, IntPtr dstRowBytes, int srcX, int srcY); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_surface_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_surfaceprops_delete(IntPtr props); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_surfaceprops_get_flags(IntPtr props); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKPixelGeometry sk_surfaceprops_get_pixel_geometry(IntPtr props); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_surfaceprops_new(uint flags, SKPixelGeometry geometry); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_svgcanvas_create_with_stream(SKRect* bounds, IntPtr stream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_svgcanvas_create_with_writer(SKRect* bounds, IntPtr writer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_textblob_builder_alloc_run(IntPtr builder, IntPtr font, int count, float x, float y, SKRect* bounds, SKRunBufferInternal* runbuffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_textblob_builder_alloc_run_pos(IntPtr builder, IntPtr font, int count, SKRect* bounds, SKRunBufferInternal* runbuffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_textblob_builder_alloc_run_pos_h(IntPtr builder, IntPtr font, int count, float y, SKRect* bounds, SKRunBufferInternal* runbuffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_textblob_builder_alloc_run_rsxform(IntPtr builder, IntPtr font, int count, SKRunBufferInternal* runbuffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_textblob_builder_alloc_run_text(IntPtr builder, IntPtr font, int count, float x, float y, int textByteCount, SKRect* bounds, SKRunBufferInternal* runbuffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_textblob_builder_alloc_run_text_pos(IntPtr builder, IntPtr font, int count, int textByteCount, SKRect* bounds, SKRunBufferInternal* runbuffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_textblob_builder_alloc_run_text_pos_h(IntPtr builder, IntPtr font, int count, float y, int textByteCount, SKRect* bounds, SKRunBufferInternal* runbuffer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_textblob_builder_delete(IntPtr builder); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_textblob_builder_make(IntPtr builder); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_textblob_builder_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_textblob_get_bounds(IntPtr blob, SKRect* bounds); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int sk_textblob_get_intercepts(IntPtr blob, float* bounds, float* intervals, IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern uint sk_textblob_get_unique_id(IntPtr blob); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_textblob_ref(IntPtr blob); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_textblob_unref(IntPtr blob); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_fontmgr_count_families(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_create_default(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_create_from_data(IntPtr param0, IntPtr data, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_fontmgr_create_from_file(IntPtr param0, void* path, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_create_from_stream(IntPtr param0, IntPtr stream, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_create_styleset(IntPtr param0, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_fontmgr_get_family_name(IntPtr param0, int index, IntPtr familyName); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_match_face_style(IntPtr param0, IntPtr face, IntPtr style); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_match_family(IntPtr param0, IntPtr familyName); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_match_family_style(IntPtr param0, IntPtr familyName, IntPtr style); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_match_family_style_character(IntPtr param0, IntPtr familyName, IntPtr style, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] bcp47, int bcp47Count, int character); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontmgr_ref_default(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_fontmgr_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_fontstyle_delete(IntPtr fs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKFontStyleSlant sk_fontstyle_get_slant(IntPtr fs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_fontstyle_get_weight(IntPtr fs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_fontstyle_get_width(IntPtr fs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontstyle_new(int weight, int width, SKFontStyleSlant slant); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontstyleset_create_empty(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontstyleset_create_typeface(IntPtr fss, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_fontstyleset_get_count(IntPtr fss); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_fontstyleset_get_style(IntPtr fss, int index, IntPtr fs, IntPtr style); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_fontstyleset_match_style(IntPtr fss, IntPtr style); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_fontstyleset_unref(IntPtr fss); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_copy_table_data(IntPtr typeface, uint tag); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_typeface_count_glyphs(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_typeface_count_tables(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_create_default(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_create_from_data(IntPtr data, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_typeface_create_from_file(void* path, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_create_from_name(IntPtr familyName, IntPtr style); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_create_from_stream(IntPtr stream, int index); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_get_family_name(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKFontStyleSlant sk_typeface_get_font_slant(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_typeface_get_font_weight(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_typeface_get_font_width(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_get_fontstyle(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe static extern bool sk_typeface_get_kerning_pair_adjustments(IntPtr typeface, ushort* glyphs, int count, int* adjustments); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_typeface_get_table_data(IntPtr typeface, uint tag, IntPtr offset, IntPtr length, void* data); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_get_table_size(IntPtr typeface, uint tag); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int sk_typeface_get_table_tags(IntPtr typeface, uint* tags); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern int sk_typeface_get_units_per_em(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool sk_typeface_is_fixed_pitch(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_typeface_open_stream(IntPtr typeface, int* ttcIndex); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_typeface_ref_default(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern ushort sk_typeface_unichar_to_glyph(IntPtr typeface, int unichar); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern void sk_typeface_unichars_to_glyphs(IntPtr typeface, int* unichars, int count, ushort* glyphs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_typeface_unref(IntPtr typeface); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_vertices_make_copy(SKVertexMode vmode, int vertexCount, SKPoint* positions, SKPoint* texs, uint* colors, int indexCount, ushort* indices); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_vertices_ref(IntPtr cvertices); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_vertices_unref(IntPtr cvertices); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_xmlstreamwriter_delete(IntPtr writer); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_xmlstreamwriter_new(IntPtr stream); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_compatpaint_clone(IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_compatpaint_delete(IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_compatpaint_get_font(IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKTextAlign sk_compatpaint_get_text_align(IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern SKTextEncoding sk_compatpaint_get_text_encoding(IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_compatpaint_make_font(IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_compatpaint_new(); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr sk_compatpaint_new_with_font(IntPtr font); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_compatpaint_reset(IntPtr paint); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_compatpaint_set_text_align(IntPtr paint, SKTextAlign align); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_compatpaint_set_text_encoding(IntPtr paint, SKTextEncoding encoding); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_manageddrawable_new(void* context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_manageddrawable_set_procs(SKManagedDrawableDelegates procs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_manageddrawable_unref(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_managedstream_destroy(IntPtr s); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_managedstream_new(void* context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_managedstream_set_procs(SKManagedStreamDelegates procs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_managedwstream_destroy(IntPtr s); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_managedwstream_new(void* context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_managedwstream_set_procs(SKManagedWStreamDelegates procs); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_managedtracememorydump_delete(IntPtr param0); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern IntPtr sk_managedtracememorydump_new([MarshalAs(UnmanagedType.I1)] bool detailed, [MarshalAs(UnmanagedType.I1)] bool dumpWrapped, void* context); [DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)] internal static extern void sk_managedtracememorydump_set_procs(SKManagedTraceMemoryDumpDelegates procs); } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GRGlFuncPtr(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr GRGlGetProcProxyDelegate(void* ctx, void* name); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GRVkFuncPtr(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr GRVkGetProcProxyDelegate(void* ctx, void* name, IntPtr instance, IntPtr device); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKBitmapReleaseProxyDelegate(void* addr, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKDataReleaseProxyDelegate(void* ptr, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKGlyphPathProxyDelegate(IntPtr pathOrNull, SKMatrix* matrix, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKImageRasterReleaseProxyDelegate(void* addr, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKImageTextureReleaseProxyDelegate(void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKManagedDrawableDestroyProxyDelegate(IntPtr d, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKManagedDrawableDrawProxyDelegate(IntPtr d, void* context, IntPtr ccanvas); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKManagedDrawableGetBoundsProxyDelegate(IntPtr d, void* context, SKRect* rect); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr SKManagedDrawableNewPictureSnapshotProxyDelegate(IntPtr d, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKManagedStreamDestroyProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr SKManagedStreamDuplicateProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr SKManagedStreamForkProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr SKManagedStreamGetLengthProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr SKManagedStreamGetPositionProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe delegate bool SKManagedStreamHasLengthProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe delegate bool SKManagedStreamHasPositionProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe delegate bool SKManagedStreamIsAtEndProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe delegate bool SKManagedStreamMoveProxyDelegate(IntPtr s, void* context, int offset); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr SKManagedStreamPeekProxyDelegate(IntPtr s, void* context, void* buffer, IntPtr size); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr SKManagedStreamReadProxyDelegate(IntPtr s, void* context, void* buffer, IntPtr size); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe delegate bool SKManagedStreamRewindProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe delegate bool SKManagedStreamSeekProxyDelegate(IntPtr s, void* context, IntPtr position); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKManagedTraceMemoryDumpDumpNumericValueProxyDelegate(IntPtr d, void* context, void* dumpName, void* valueName, void* units, ulong value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKManagedTraceMemoryDumpDumpStringValueProxyDelegate(IntPtr d, void* context, void* dumpName, void* valueName, void* value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate IntPtr SKManagedWStreamBytesWrittenProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKManagedWStreamDestroyProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKManagedWStreamFlushProxyDelegate(IntPtr s, void* context); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal unsafe delegate bool SKManagedWStreamWriteProxyDelegate(IntPtr s, void* context, void* buffer, IntPtr size); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal unsafe delegate void SKSurfaceRasterReleaseProxyDelegate(void* addr, void* context); internal struct GRContextOptionsNative : IEquatable { public byte fAvoidStencilBuffers; public int fRuntimeProgramCacheSize; public IntPtr fGlyphCacheTextureMaximumBytes; public byte fAllowPathMaskCaching; public byte fDoManualMipmapping; public int fBufferMapThreshold; public readonly bool Equals(GRContextOptionsNative obj) { if (fAvoidStencilBuffers == obj.fAvoidStencilBuffers && fRuntimeProgramCacheSize == obj.fRuntimeProgramCacheSize && fGlyphCacheTextureMaximumBytes == obj.fGlyphCacheTextureMaximumBytes && fAllowPathMaskCaching == obj.fAllowPathMaskCaching && fDoManualMipmapping == obj.fDoManualMipmapping) { return fBufferMapThreshold == obj.fBufferMapThreshold; } return false; } public override readonly bool Equals(object obj) { if (obj is GRContextOptionsNative obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRContextOptionsNative left, GRContextOptionsNative right) { return left.Equals(right); } public static bool operator !=(GRContextOptionsNative left, GRContextOptionsNative right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fAvoidStencilBuffers); hashCode.Add(fRuntimeProgramCacheSize); hashCode.Add(fGlyphCacheTextureMaximumBytes); hashCode.Add(fAllowPathMaskCaching); hashCode.Add(fDoManualMipmapping); hashCode.Add(fBufferMapThreshold); return hashCode.ToHashCode(); } } internal struct GRMtlTextureInfoNative : IEquatable { public unsafe void* fTexture; public unsafe readonly bool Equals(GRMtlTextureInfoNative obj) { return fTexture == obj.fTexture; } public override readonly bool Equals(object obj) { if (obj is GRMtlTextureInfoNative obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRMtlTextureInfoNative left, GRMtlTextureInfoNative right) { return left.Equals(right); } public static bool operator !=(GRMtlTextureInfoNative left, GRMtlTextureInfoNative right) { return !left.Equals(right); } public unsafe override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fTexture); return hashCode.ToHashCode(); } } public struct GRVkAlloc : IEquatable { private ulong fMemory; private ulong fOffset; private ulong fSize; private uint fFlags; private IntPtr fBackendMemory; private byte fUsesSystemHeap; public ulong Memory { readonly get { return fMemory; } set { fMemory = value; } } public ulong Offset { readonly get { return fOffset; } set { fOffset = value; } } public ulong Size { readonly get { return fSize; } set { fSize = value; } } public uint Flags { readonly get { return fFlags; } set { fFlags = value; } } public IntPtr BackendMemory { readonly get { return fBackendMemory; } set { fBackendMemory = value; } } public readonly bool Equals(GRVkAlloc obj) { if (fMemory == obj.fMemory && fOffset == obj.fOffset && fSize == obj.fSize && fFlags == obj.fFlags && fBackendMemory == obj.fBackendMemory) { return fUsesSystemHeap == obj.fUsesSystemHeap; } return false; } public override readonly bool Equals(object obj) { if (obj is GRVkAlloc obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRVkAlloc left, GRVkAlloc right) { return left.Equals(right); } public static bool operator !=(GRVkAlloc left, GRVkAlloc right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fMemory); hashCode.Add(fOffset); hashCode.Add(fSize); hashCode.Add(fFlags); hashCode.Add(fBackendMemory); hashCode.Add(fUsesSystemHeap); return hashCode.ToHashCode(); } } internal struct GRVkBackendContextNative : IEquatable { public IntPtr fInstance; public IntPtr fPhysicalDevice; public IntPtr fDevice; public IntPtr fQueue; public uint fGraphicsQueueIndex; public uint fMinAPIVersion; public uint fInstanceVersion; public uint fMaxAPIVersion; public uint fExtensions; public IntPtr fVkExtensions; public uint fFeatures; public IntPtr fDeviceFeatures; public IntPtr fDeviceFeatures2; public IntPtr fMemoryAllocator; public GRVkGetProcProxyDelegate fGetProc; public unsafe void* fGetProcUserData; public byte fOwnsInstanceAndDevice; public byte fProtectedContext; public unsafe readonly bool Equals(GRVkBackendContextNative obj) { if (fInstance == obj.fInstance && fPhysicalDevice == obj.fPhysicalDevice && fDevice == obj.fDevice && fQueue == obj.fQueue && fGraphicsQueueIndex == obj.fGraphicsQueueIndex && fMinAPIVersion == obj.fMinAPIVersion && fInstanceVersion == obj.fInstanceVersion && fMaxAPIVersion == obj.fMaxAPIVersion && fExtensions == obj.fExtensions && fVkExtensions == obj.fVkExtensions && fFeatures == obj.fFeatures && fDeviceFeatures == obj.fDeviceFeatures && fDeviceFeatures2 == obj.fDeviceFeatures2 && fMemoryAllocator == obj.fMemoryAllocator && fGetProc == obj.fGetProc && fGetProcUserData == obj.fGetProcUserData && fOwnsInstanceAndDevice == obj.fOwnsInstanceAndDevice) { return fProtectedContext == obj.fProtectedContext; } return false; } public override readonly bool Equals(object obj) { if (obj is GRVkBackendContextNative obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRVkBackendContextNative left, GRVkBackendContextNative right) { return left.Equals(right); } public static bool operator !=(GRVkBackendContextNative left, GRVkBackendContextNative right) { return !left.Equals(right); } public unsafe override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fInstance); hashCode.Add(fPhysicalDevice); hashCode.Add(fDevice); hashCode.Add(fQueue); hashCode.Add(fGraphicsQueueIndex); hashCode.Add(fMinAPIVersion); hashCode.Add(fInstanceVersion); hashCode.Add(fMaxAPIVersion); hashCode.Add(fExtensions); hashCode.Add(fVkExtensions); hashCode.Add(fFeatures); hashCode.Add(fDeviceFeatures); hashCode.Add(fDeviceFeatures2); hashCode.Add(fMemoryAllocator); hashCode.Add(fGetProc); hashCode.Add(fGetProcUserData); hashCode.Add(fOwnsInstanceAndDevice); hashCode.Add(fProtectedContext); return hashCode.ToHashCode(); } } public struct GRVkImageInfo : IEquatable { private ulong fImage; private GRVkAlloc fAlloc; private uint fImageTiling; private uint fImageLayout; private uint fFormat; private uint fImageUsageFlags; private uint fSampleCount; private uint fLevelCount; private uint fCurrentQueueFamily; private byte fProtected; private GrVkYcbcrConversionInfo fYcbcrConversionInfo; private uint fSharingMode; public ulong Image { readonly get { return fImage; } set { fImage = value; } } public GRVkAlloc Alloc { readonly get { return fAlloc; } set { fAlloc = value; } } public uint ImageTiling { readonly get { return fImageTiling; } set { fImageTiling = value; } } public uint ImageLayout { readonly get { return fImageLayout; } set { fImageLayout = value; } } public uint Format { readonly get { return fFormat; } set { fFormat = value; } } public uint ImageUsageFlags { readonly get { return fImageUsageFlags; } set { fImageUsageFlags = value; } } public uint SampleCount { readonly get { return fSampleCount; } set { fSampleCount = value; } } public uint LevelCount { readonly get { return fLevelCount; } set { fLevelCount = value; } } public uint CurrentQueueFamily { readonly get { return fCurrentQueueFamily; } set { fCurrentQueueFamily = value; } } public bool Protected { readonly get { return fProtected > 0; } set { fProtected = (value ? ((byte)1) : ((byte)0)); } } public GrVkYcbcrConversionInfo YcbcrConversionInfo { readonly get { return fYcbcrConversionInfo; } set { fYcbcrConversionInfo = value; } } public uint SharingMode { readonly get { return fSharingMode; } set { fSharingMode = value; } } public readonly bool Equals(GRVkImageInfo obj) { if (fImage == obj.fImage && fAlloc == obj.fAlloc && fImageTiling == obj.fImageTiling && fImageLayout == obj.fImageLayout && fFormat == obj.fFormat && fImageUsageFlags == obj.fImageUsageFlags && fSampleCount == obj.fSampleCount && fLevelCount == obj.fLevelCount && fCurrentQueueFamily == obj.fCurrentQueueFamily && fProtected == obj.fProtected && fYcbcrConversionInfo == obj.fYcbcrConversionInfo) { return fSharingMode == obj.fSharingMode; } return false; } public override readonly bool Equals(object obj) { if (obj is GRVkImageInfo obj2) { return Equals(obj2); } return false; } public static bool operator ==(GRVkImageInfo left, GRVkImageInfo right) { return left.Equals(right); } public static bool operator !=(GRVkImageInfo left, GRVkImageInfo right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fImage); hashCode.Add(fAlloc); hashCode.Add(fImageTiling); hashCode.Add(fImageLayout); hashCode.Add(fFormat); hashCode.Add(fImageUsageFlags); hashCode.Add(fSampleCount); hashCode.Add(fLevelCount); hashCode.Add(fCurrentQueueFamily); hashCode.Add(fProtected); hashCode.Add(fYcbcrConversionInfo); hashCode.Add(fSharingMode); return hashCode.ToHashCode(); } } public struct GrVkYcbcrConversionInfo : IEquatable { private uint fFormat; private ulong fExternalFormat; private uint fYcbcrModel; private uint fYcbcrRange; private uint fXChromaOffset; private uint fYChromaOffset; private uint fChromaFilter; private uint fForceExplicitReconstruction; private uint fFormatFeatures; public uint Format { readonly get { return fFormat; } set { fFormat = value; } } public ulong ExternalFormat { readonly get { return fExternalFormat; } set { fExternalFormat = value; } } public uint YcbcrModel { readonly get { return fYcbcrModel; } set { fYcbcrModel = value; } } public uint YcbcrRange { readonly get { return fYcbcrRange; } set { fYcbcrRange = value; } } public uint XChromaOffset { readonly get { return fXChromaOffset; } set { fXChromaOffset = value; } } public uint YChromaOffset { readonly get { return fYChromaOffset; } set { fYChromaOffset = value; } } public uint ChromaFilter { readonly get { return fChromaFilter; } set { fChromaFilter = value; } } public uint ForceExplicitReconstruction { readonly get { return fForceExplicitReconstruction; } set { fForceExplicitReconstruction = value; } } public uint FormatFeatures { readonly get { return fFormatFeatures; } set { fFormatFeatures = value; } } public readonly bool Equals(GrVkYcbcrConversionInfo obj) { if (fFormat == obj.fFormat && fExternalFormat == obj.fExternalFormat && fYcbcrModel == obj.fYcbcrModel && fYcbcrRange == obj.fYcbcrRange && fXChromaOffset == obj.fXChromaOffset && fYChromaOffset == obj.fYChromaOffset && fChromaFilter == obj.fChromaFilter && fForceExplicitReconstruction == obj.fForceExplicitReconstruction) { return fFormatFeatures == obj.fFormatFeatures; } return false; } public override readonly bool Equals(object obj) { if (obj is GrVkYcbcrConversionInfo obj2) { return Equals(obj2); } return false; } public static bool operator ==(GrVkYcbcrConversionInfo left, GrVkYcbcrConversionInfo right) { return left.Equals(right); } public static bool operator !=(GrVkYcbcrConversionInfo left, GrVkYcbcrConversionInfo right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fFormat); hashCode.Add(fExternalFormat); hashCode.Add(fYcbcrModel); hashCode.Add(fYcbcrRange); hashCode.Add(fXChromaOffset); hashCode.Add(fYChromaOffset); hashCode.Add(fChromaFilter); hashCode.Add(fForceExplicitReconstruction); hashCode.Add(fFormatFeatures); return hashCode.ToHashCode(); } } public struct SKCodecFrameInfo : IEquatable { private int fRequiredFrame; private int fDuration; private byte fFullyReceived; private SKAlphaType fAlphaType; private SKCodecAnimationDisposalMethod fDisposalMethod; public int RequiredFrame { readonly get { return fRequiredFrame; } set { fRequiredFrame = value; } } public int Duration { readonly get { return fDuration; } set { fDuration = value; } } public bool FullyRecieved { readonly get { return fFullyReceived > 0; } set { fFullyReceived = (value ? ((byte)1) : ((byte)0)); } } public SKAlphaType AlphaType { readonly get { return fAlphaType; } set { fAlphaType = value; } } public SKCodecAnimationDisposalMethod DisposalMethod { readonly get { return fDisposalMethod; } set { fDisposalMethod = value; } } public readonly bool Equals(SKCodecFrameInfo obj) { if (fRequiredFrame == obj.fRequiredFrame && fDuration == obj.fDuration && fFullyReceived == obj.fFullyReceived && fAlphaType == obj.fAlphaType) { return fDisposalMethod == obj.fDisposalMethod; } return false; } public override readonly bool Equals(object obj) { if (obj is SKCodecFrameInfo obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKCodecFrameInfo left, SKCodecFrameInfo right) { return left.Equals(right); } public static bool operator !=(SKCodecFrameInfo left, SKCodecFrameInfo right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fRequiredFrame); hashCode.Add(fDuration); hashCode.Add(fFullyReceived); hashCode.Add(fAlphaType); hashCode.Add(fDisposalMethod); return hashCode.ToHashCode(); } } internal struct SKCodecOptionsInternal : IEquatable { public SKZeroInitialized fZeroInitialized; public unsafe SKRectI* fSubset; public int fFrameIndex; public int fPriorFrame; public unsafe readonly bool Equals(SKCodecOptionsInternal obj) { if (fZeroInitialized == obj.fZeroInitialized && fSubset == obj.fSubset && fFrameIndex == obj.fFrameIndex) { return fPriorFrame == obj.fPriorFrame; } return false; } public override readonly bool Equals(object obj) { if (obj is SKCodecOptionsInternal obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKCodecOptionsInternal left, SKCodecOptionsInternal right) { return left.Equals(right); } public static bool operator !=(SKCodecOptionsInternal left, SKCodecOptionsInternal right) { return !left.Equals(right); } public unsafe override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fZeroInitialized); hashCode.Add((void*)fSubset); hashCode.Add(fFrameIndex); hashCode.Add(fPriorFrame); return hashCode.ToHashCode(); } } internal struct SKDocumentPdfMetadataInternal : IEquatable { public IntPtr fTitle; public IntPtr fAuthor; public IntPtr fSubject; public IntPtr fKeywords; public IntPtr fCreator; public IntPtr fProducer; public unsafe SKTimeDateTimeInternal* fCreation; public unsafe SKTimeDateTimeInternal* fModified; public float fRasterDPI; public byte fPDFA; public int fEncodingQuality; public unsafe readonly bool Equals(SKDocumentPdfMetadataInternal obj) { if (fTitle == obj.fTitle && fAuthor == obj.fAuthor && fSubject == obj.fSubject && fKeywords == obj.fKeywords && fCreator == obj.fCreator && fProducer == obj.fProducer && fCreation == obj.fCreation && fModified == obj.fModified && fRasterDPI == obj.fRasterDPI && fPDFA == obj.fPDFA) { return fEncodingQuality == obj.fEncodingQuality; } return false; } public override readonly bool Equals(object obj) { if (obj is SKDocumentPdfMetadataInternal obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKDocumentPdfMetadataInternal left, SKDocumentPdfMetadataInternal right) { return left.Equals(right); } public static bool operator !=(SKDocumentPdfMetadataInternal left, SKDocumentPdfMetadataInternal right) { return !left.Equals(right); } public unsafe override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fTitle); hashCode.Add(fAuthor); hashCode.Add(fSubject); hashCode.Add(fKeywords); hashCode.Add(fCreator); hashCode.Add(fProducer); hashCode.Add((void*)fCreation); hashCode.Add((void*)fModified); hashCode.Add(fRasterDPI); hashCode.Add(fPDFA); hashCode.Add(fEncodingQuality); return hashCode.ToHashCode(); } } internal struct SKImageInfoNative : IEquatable { public IntPtr colorspace; public int width; public int height; public SKColorTypeNative colorType; public SKAlphaType alphaType; public readonly bool Equals(SKImageInfoNative obj) { if (colorspace == obj.colorspace && width == obj.width && height == obj.height && colorType == obj.colorType) { return alphaType == obj.alphaType; } return false; } public override readonly bool Equals(object obj) { if (obj is SKImageInfoNative obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKImageInfoNative left, SKImageInfoNative right) { return left.Equals(right); } public static bool operator !=(SKImageInfoNative left, SKImageInfoNative right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(colorspace); hashCode.Add(width); hashCode.Add(height); hashCode.Add(colorType); hashCode.Add(alphaType); return hashCode.ToHashCode(); } public static void UpdateNative(ref SKImageInfo managed, ref SKImageInfoNative native) { native.colorspace = managed.ColorSpace?.Handle ?? IntPtr.Zero; native.width = managed.Width; native.height = managed.Height; native.colorType = managed.ColorType.ToNative(); native.alphaType = managed.AlphaType; } public static SKImageInfoNative FromManaged(ref SKImageInfo managed) { return new SKImageInfoNative { colorspace = (managed.ColorSpace?.Handle ?? IntPtr.Zero), width = managed.Width, height = managed.Height, colorType = managed.ColorType.ToNative(), alphaType = managed.AlphaType }; } public static SKImageInfo ToManaged(ref SKImageInfoNative native) { return new SKImageInfo { ColorSpace = SKColorSpace.GetObject(native.colorspace), Width = native.width, Height = native.height, ColorType = native.colorType.FromNative(), AlphaType = native.alphaType }; } } internal struct SKLatticeInternal : IEquatable { public unsafe int* fXDivs; public unsafe int* fYDivs; public unsafe SKLatticeRectType* fRectTypes; public int fXCount; public int fYCount; public unsafe SKRectI* fBounds; public unsafe uint* fColors; public unsafe readonly bool Equals(SKLatticeInternal obj) { if (fXDivs == obj.fXDivs && fYDivs == obj.fYDivs && fRectTypes == obj.fRectTypes && fXCount == obj.fXCount && fYCount == obj.fYCount && fBounds == obj.fBounds) { return fColors == obj.fColors; } return false; } public override readonly bool Equals(object obj) { if (obj is SKLatticeInternal obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKLatticeInternal left, SKLatticeInternal right) { return left.Equals(right); } public static bool operator !=(SKLatticeInternal left, SKLatticeInternal right) { return !left.Equals(right); } public unsafe override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add((void*)fXDivs); hashCode.Add((void*)fYDivs); hashCode.Add((void*)fRectTypes); hashCode.Add(fXCount); hashCode.Add(fYCount); hashCode.Add((void*)fBounds); hashCode.Add((void*)fColors); return hashCode.ToHashCode(); } } internal struct SKManagedDrawableDelegates : IEquatable { public SKManagedDrawableDrawProxyDelegate fDraw; public SKManagedDrawableGetBoundsProxyDelegate fGetBounds; public SKManagedDrawableNewPictureSnapshotProxyDelegate fNewPictureSnapshot; public SKManagedDrawableDestroyProxyDelegate fDestroy; public readonly bool Equals(SKManagedDrawableDelegates obj) { if (fDraw == obj.fDraw && fGetBounds == obj.fGetBounds && fNewPictureSnapshot == obj.fNewPictureSnapshot) { return fDestroy == obj.fDestroy; } return false; } public override readonly bool Equals(object obj) { if (obj is SKManagedDrawableDelegates obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKManagedDrawableDelegates left, SKManagedDrawableDelegates right) { return left.Equals(right); } public static bool operator !=(SKManagedDrawableDelegates left, SKManagedDrawableDelegates right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fDraw); hashCode.Add(fGetBounds); hashCode.Add(fNewPictureSnapshot); hashCode.Add(fDestroy); return hashCode.ToHashCode(); } } internal struct SKManagedStreamDelegates : IEquatable { public SKManagedStreamReadProxyDelegate fRead; public SKManagedStreamPeekProxyDelegate fPeek; public SKManagedStreamIsAtEndProxyDelegate fIsAtEnd; public SKManagedStreamHasPositionProxyDelegate fHasPosition; public SKManagedStreamHasLengthProxyDelegate fHasLength; public SKManagedStreamRewindProxyDelegate fRewind; public SKManagedStreamGetPositionProxyDelegate fGetPosition; public SKManagedStreamSeekProxyDelegate fSeek; public SKManagedStreamMoveProxyDelegate fMove; public SKManagedStreamGetLengthProxyDelegate fGetLength; public SKManagedStreamDuplicateProxyDelegate fDuplicate; public SKManagedStreamForkProxyDelegate fFork; public SKManagedStreamDestroyProxyDelegate fDestroy; public readonly bool Equals(SKManagedStreamDelegates obj) { if (fRead == obj.fRead && fPeek == obj.fPeek && fIsAtEnd == obj.fIsAtEnd && fHasPosition == obj.fHasPosition && fHasLength == obj.fHasLength && fRewind == obj.fRewind && fGetPosition == obj.fGetPosition && fSeek == obj.fSeek && fMove == obj.fMove && fGetLength == obj.fGetLength && fDuplicate == obj.fDuplicate && fFork == obj.fFork) { return fDestroy == obj.fDestroy; } return false; } public override readonly bool Equals(object obj) { if (obj is SKManagedStreamDelegates obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKManagedStreamDelegates left, SKManagedStreamDelegates right) { return left.Equals(right); } public static bool operator !=(SKManagedStreamDelegates left, SKManagedStreamDelegates right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fRead); hashCode.Add(fPeek); hashCode.Add(fIsAtEnd); hashCode.Add(fHasPosition); hashCode.Add(fHasLength); hashCode.Add(fRewind); hashCode.Add(fGetPosition); hashCode.Add(fSeek); hashCode.Add(fMove); hashCode.Add(fGetLength); hashCode.Add(fDuplicate); hashCode.Add(fFork); hashCode.Add(fDestroy); return hashCode.ToHashCode(); } } internal struct SKManagedTraceMemoryDumpDelegates : IEquatable { public SKManagedTraceMemoryDumpDumpNumericValueProxyDelegate fDumpNumericValue; public SKManagedTraceMemoryDumpDumpStringValueProxyDelegate fDumpStringValue; public readonly bool Equals(SKManagedTraceMemoryDumpDelegates obj) { if (fDumpNumericValue == obj.fDumpNumericValue) { return fDumpStringValue == obj.fDumpStringValue; } return false; } public override readonly bool Equals(object obj) { if (obj is SKManagedTraceMemoryDumpDelegates obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKManagedTraceMemoryDumpDelegates left, SKManagedTraceMemoryDumpDelegates right) { return left.Equals(right); } public static bool operator !=(SKManagedTraceMemoryDumpDelegates left, SKManagedTraceMemoryDumpDelegates right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fDumpNumericValue); hashCode.Add(fDumpStringValue); return hashCode.ToHashCode(); } } internal struct SKManagedWStreamDelegates : IEquatable { public SKManagedWStreamWriteProxyDelegate fWrite; public SKManagedWStreamFlushProxyDelegate fFlush; public SKManagedWStreamBytesWrittenProxyDelegate fBytesWritten; public SKManagedWStreamDestroyProxyDelegate fDestroy; public readonly bool Equals(SKManagedWStreamDelegates obj) { if (fWrite == obj.fWrite && fFlush == obj.fFlush && fBytesWritten == obj.fBytesWritten) { return fDestroy == obj.fDestroy; } return false; } public override readonly bool Equals(object obj) { if (obj is SKManagedWStreamDelegates obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKManagedWStreamDelegates left, SKManagedWStreamDelegates right) { return left.Equals(right); } public static bool operator !=(SKManagedWStreamDelegates left, SKManagedWStreamDelegates right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fWrite); hashCode.Add(fFlush); hashCode.Add(fBytesWritten); hashCode.Add(fDestroy); return hashCode.ToHashCode(); } } public struct SKMask : IEquatable { private unsafe byte* fImage; private SKRectI fBounds; private uint fRowBytes; private SKMaskFormat fFormat; public unsafe IntPtr Image { readonly get { return (IntPtr)fImage; } set { fImage = (byte*)(void*)value; } } public SKRectI Bounds { readonly get { return fBounds; } set { fBounds = value; } } public uint RowBytes { readonly get { return fRowBytes; } set { fRowBytes = value; } } public SKMaskFormat Format { readonly get { return fFormat; } set { fFormat = value; } } public unsafe readonly bool IsEmpty { get { fixed (SKMask* cmask = &this) { return SkiaApi.sk_mask_is_empty(cmask); } } } public unsafe readonly bool Equals(SKMask obj) { if (fImage == obj.fImage && fBounds == obj.fBounds && fRowBytes == obj.fRowBytes) { return fFormat == obj.fFormat; } return false; } public override readonly bool Equals(object obj) { if (obj is SKMask obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKMask left, SKMask right) { return left.Equals(right); } public static bool operator !=(SKMask left, SKMask right) { return !left.Equals(right); } public unsafe override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add((void*)fImage); hashCode.Add(fBounds); hashCode.Add(fRowBytes); hashCode.Add(fFormat); return hashCode.ToHashCode(); } public unsafe SKMask(IntPtr image, SKRectI bounds, uint rowBytes, SKMaskFormat format) { fBounds = bounds; fRowBytes = rowBytes; fFormat = format; fImage = (byte*)(void*)image; } public unsafe SKMask(SKRectI bounds, uint rowBytes, SKMaskFormat format) { fBounds = bounds; fRowBytes = rowBytes; fFormat = format; fImage = null; } public unsafe Span GetImageSpan() { return new Span((void*)Image, (int)ComputeTotalImageSize()); } public unsafe long AllocateImage() { fixed (SKMask* cmask = &this) { IntPtr intPtr = SkiaApi.sk_mask_compute_total_image_size(cmask); fImage = SkiaApi.sk_mask_alloc_image(intPtr); return (long)intPtr; } } public unsafe void FreeImage() { if (fImage != null) { FreeImage((IntPtr)fImage); fImage = null; } } public unsafe readonly long ComputeImageSize() { fixed (SKMask* cmask = &this) { return (long)SkiaApi.sk_mask_compute_image_size(cmask); } } public unsafe readonly long ComputeTotalImageSize() { fixed (SKMask* cmask = &this) { return (long)SkiaApi.sk_mask_compute_total_image_size(cmask); } } public unsafe readonly byte GetAddr1(int x, int y) { fixed (SKMask* cmask = &this) { return *SkiaApi.sk_mask_get_addr_1(cmask, x, y); } } public unsafe readonly byte GetAddr8(int x, int y) { fixed (SKMask* cmask = &this) { return *SkiaApi.sk_mask_get_addr_8(cmask, x, y); } } public unsafe readonly ushort GetAddr16(int x, int y) { fixed (SKMask* cmask = &this) { return *SkiaApi.sk_mask_get_addr_lcd_16(cmask, x, y); } } public unsafe readonly uint GetAddr32(int x, int y) { fixed (SKMask* cmask = &this) { return *SkiaApi.sk_mask_get_addr_32(cmask, x, y); } } public unsafe readonly IntPtr GetAddr(int x, int y) { fixed (SKMask* cmask = &this) { return (IntPtr)SkiaApi.sk_mask_get_addr(cmask, x, y); } } public unsafe static IntPtr AllocateImage(long size) { return (IntPtr)SkiaApi.sk_mask_alloc_image((IntPtr)size); } public unsafe static void FreeImage(IntPtr image) { SkiaApi.sk_mask_free_image((void*)image); } public static SKMask Create(byte[] image, SKRectI bounds, uint rowBytes, SKMaskFormat format) { return Create(image.AsSpan(), bounds, rowBytes, format); } public unsafe static SKMask Create(ReadOnlySpan image, SKRectI bounds, uint rowBytes, SKMaskFormat format) { SKMask result = new SKMask(bounds, rowBytes, format); int num = (int)result.ComputeTotalImageSize(); if (image.Length != num) { long num2 = bounds.Height * rowBytes; string message = string.Format("Length of image ({0}) does not match the computed size of the mask ({1}). Check the {2} and {3}.", image.Length, num2, "bounds", "rowBytes"); throw new ArgumentException(message); } result.AllocateImage(); image.CopyTo(new Span((void*)result.Image, num)); return result; } } public struct SKMatrix : IEquatable { private class Indices { public const int ScaleX = 0; public const int SkewX = 1; public const int TransX = 2; public const int SkewY = 3; public const int ScaleY = 4; public const int TransY = 5; public const int Persp0 = 6; public const int Persp1 = 7; public const int Persp2 = 8; public const int Count = 9; } private float scaleX; private float skewX; private float transX; private float skewY; private float scaleY; private float transY; private float persp0; private float persp1; private float persp2; internal const float DegreesToRadians = MathF.PI / 180f; public static readonly SKMatrix Empty; public static readonly SKMatrix Identity = new SKMatrix { scaleX = 1f, scaleY = 1f, persp2 = 1f }; public float ScaleX { readonly get { return scaleX; } set { scaleX = value; } } public float SkewX { readonly get { return skewX; } set { skewX = value; } } public float TransX { readonly get { return transX; } set { transX = value; } } public float SkewY { readonly get { return skewY; } set { skewY = value; } } public float ScaleY { readonly get { return scaleY; } set { scaleY = value; } } public float TransY { readonly get { return transY; } set { transY = value; } } public float Persp0 { readonly get { return persp0; } set { persp0 = value; } } public float Persp1 { readonly get { return persp1; } set { persp1 = value; } } public float Persp2 { readonly get { return persp2; } set { persp2 = value; } } public readonly bool IsIdentity => Equals(Identity); public float[] Values { readonly get { return new float[9] { scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2 }; } set { if (value == null) { throw new ArgumentNullException("Values"); } if (value.Length != 9) { throw new ArgumentException($"The matrix array must have a length of {9}.", "Values"); } scaleX = value[0]; skewX = value[1]; transX = value[2]; skewY = value[3]; scaleY = value[4]; transY = value[5]; persp0 = value[6]; persp1 = value[7]; persp2 = value[8]; } } public unsafe readonly bool IsInvertible { get { fixed (SKMatrix* matrix = &this) { return SkiaApi.sk_matrix_try_invert(matrix, null); } } } public readonly bool Equals(SKMatrix obj) { if (scaleX == obj.scaleX && skewX == obj.skewX && transX == obj.transX && skewY == obj.skewY && scaleY == obj.scaleY && transY == obj.transY && persp0 == obj.persp0 && persp1 == obj.persp1) { return persp2 == obj.persp2; } return false; } public override readonly bool Equals(object obj) { if (obj is SKMatrix obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKMatrix left, SKMatrix right) { return left.Equals(right); } public static bool operator !=(SKMatrix left, SKMatrix right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(scaleX); hashCode.Add(skewX); hashCode.Add(transX); hashCode.Add(skewY); hashCode.Add(scaleY); hashCode.Add(transY); hashCode.Add(persp0); hashCode.Add(persp1); hashCode.Add(persp2); return hashCode.ToHashCode(); } public SKMatrix(float[] values) { if (values == null) { throw new ArgumentNullException("values"); } if (values.Length != 9) { throw new ArgumentException($"The matrix array must have a length of {9}.", "values"); } scaleX = values[0]; skewX = values[1]; transX = values[2]; skewY = values[3]; scaleY = values[4]; transY = values[5]; persp0 = values[6]; persp1 = values[7]; persp2 = values[8]; } public SKMatrix(float scaleX, float skewX, float transX, float skewY, float scaleY, float transY, float persp0, float persp1, float persp2) { this.scaleX = scaleX; this.skewX = skewX; this.transX = transX; this.skewY = skewY; this.scaleY = scaleY; this.transY = transY; this.persp0 = persp0; this.persp1 = persp1; this.persp2 = persp2; } public readonly void GetValues(float[] values) { if (values == null) { throw new ArgumentNullException("values"); } if (values.Length != 9) { throw new ArgumentException($"The matrix array must have a length of {9}.", "values"); } values[0] = scaleX; values[1] = skewX; values[2] = transX; values[3] = skewY; values[4] = scaleY; values[5] = transY; values[6] = persp0; values[7] = persp1; values[8] = persp2; } public static SKMatrix CreateIdentity() { return new SKMatrix { scaleX = 1f, scaleY = 1f, persp2 = 1f }; } public static SKMatrix CreateTranslation(float x, float y) { if (x == 0f && y == 0f) { return Identity; } return new SKMatrix { scaleX = 1f, scaleY = 1f, transX = x, transY = y, persp2 = 1f }; } public static SKMatrix CreateScale(float x, float y) { if (x == 1f && y == 1f) { return Identity; } return new SKMatrix { scaleX = x, scaleY = y, persp2 = 1f }; } public static SKMatrix CreateScale(float x, float y, float pivotX, float pivotY) { if (x == 1f && y == 1f) { return Identity; } float num = pivotX - x * pivotX; float num2 = pivotY - y * pivotY; return new SKMatrix { scaleX = x, scaleY = y, transX = num, transY = num2, persp2 = 1f }; } public static SKMatrix CreateRotation(float radians) { if (radians == 0f) { return Identity; } float sin = (float)Math.Sin(radians); float cos = (float)Math.Cos(radians); SKMatrix matrix = Identity; SetSinCos(ref matrix, sin, cos); return matrix; } public static SKMatrix CreateRotation(float radians, float pivotX, float pivotY) { if (radians == 0f) { return Identity; } float sin = (float)Math.Sin(radians); float cos = (float)Math.Cos(radians); SKMatrix matrix = Identity; SetSinCos(ref matrix, sin, cos, pivotX, pivotY); return matrix; } public static SKMatrix CreateRotationDegrees(float degrees) { if (degrees == 0f) { return Identity; } return CreateRotation(degrees * (MathF.PI / 180f)); } public static SKMatrix CreateRotationDegrees(float degrees, float pivotX, float pivotY) { if (degrees == 0f) { return Identity; } return CreateRotation(degrees * (MathF.PI / 180f), pivotX, pivotY); } public static SKMatrix CreateSkew(float x, float y) { if (x == 0f && y == 0f) { return Identity; } return new SKMatrix { scaleX = 1f, skewX = x, skewY = y, scaleY = 1f, persp2 = 1f }; } public static SKMatrix CreateScaleTranslation(float sx, float sy, float tx, float ty) { if (sx == 0f && sy == 0f && tx == 0f && ty == 0f) { return Identity; } return new SKMatrix { scaleX = sx, skewX = 0f, transX = tx, skewY = 0f, scaleY = sy, transY = ty, persp0 = 0f, persp1 = 0f, persp2 = 1f }; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateIdentity() instead.")] public static SKMatrix MakeIdentity() { return CreateIdentity(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateScale(float, float) instead.")] public static SKMatrix MakeScale(float sx, float sy) { return CreateScale(sx, sy); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateScale(float, float, float, float) instead.")] public static SKMatrix MakeScale(float sx, float sy, float pivotX, float pivotY) { return CreateScale(sx, sy, pivotX, pivotY); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateTranslation(float, float) instead.")] public static SKMatrix MakeTranslation(float dx, float dy) { return CreateTranslation(dx, dy); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRotation(float) instead.")] public static SKMatrix MakeRotation(float radians) { return CreateRotation(radians); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRotation(float, float, float) instead.")] public static SKMatrix MakeRotation(float radians, float pivotx, float pivoty) { return CreateRotation(radians, pivotx, pivoty); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRotationDegrees(float) instead.")] public static SKMatrix MakeRotationDegrees(float degrees) { return CreateRotationDegrees(degrees); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRotationDegrees(float, float, float) instead.")] public static SKMatrix MakeRotationDegrees(float degrees, float pivotx, float pivoty) { return CreateRotationDegrees(degrees, pivotx, pivoty); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateSkew(float, float) instead.")] public static SKMatrix MakeSkew(float sx, float sy) { return CreateSkew(sx, sy); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateScaleTranslation(float, float, float, float) instead.")] public void SetScaleTranslate(float sx, float sy, float tx, float ty) { scaleX = sx; skewX = 0f; transX = tx; skewY = 0f; scaleY = sy; transY = ty; persp0 = 0f; persp1 = 0f; persp2 = 1f; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRotation(float, float, float) instead.")] public static void Rotate(ref SKMatrix matrix, float radians, float pivotx, float pivoty) { float sin = (float)Math.Sin(radians); float cos = (float)Math.Cos(radians); SetSinCos(ref matrix, sin, cos, pivotx, pivoty); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRotationDegrees(float, float, float) instead.")] public static void RotateDegrees(ref SKMatrix matrix, float degrees, float pivotx, float pivoty) { float sin = (float)Math.Sin(degrees * (MathF.PI / 180f)); float cos = (float)Math.Cos(degrees * (MathF.PI / 180f)); SetSinCos(ref matrix, sin, cos, pivotx, pivoty); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRotation(float) instead.")] public static void Rotate(ref SKMatrix matrix, float radians) { float sin = (float)Math.Sin(radians); float cos = (float)Math.Cos(radians); SetSinCos(ref matrix, sin, cos); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateRotationDegrees(float) instead.")] public static void RotateDegrees(ref SKMatrix matrix, float degrees) { float sin = (float)Math.Sin(degrees * (MathF.PI / 180f)); float cos = (float)Math.Cos(degrees * (MathF.PI / 180f)); SetSinCos(ref matrix, sin, cos); } public unsafe readonly bool TryInvert(out SKMatrix inverse) { fixed (SKMatrix* result = &inverse) { fixed (SKMatrix* matrix = &this) { return SkiaApi.sk_matrix_try_invert(matrix, result); } } } public readonly SKMatrix Invert() { if (TryInvert(out var inverse)) { return inverse; } return Empty; } public unsafe static SKMatrix Concat(SKMatrix first, SKMatrix second) { SKMatrix result = default(SKMatrix); SkiaApi.sk_matrix_concat(&result, &first, &second); return result; } public unsafe readonly SKMatrix PreConcat(SKMatrix matrix) { SKMatrix result = this; SkiaApi.sk_matrix_pre_concat(&result, &matrix); return result; } public unsafe readonly SKMatrix PostConcat(SKMatrix matrix) { SKMatrix result = this; SkiaApi.sk_matrix_post_concat(&result, &matrix); return result; } public unsafe static void Concat(ref SKMatrix target, SKMatrix first, SKMatrix second) { fixed (SKMatrix* result = &target) { SkiaApi.sk_matrix_concat(result, &first, &second); } } public unsafe static void Concat(ref SKMatrix target, ref SKMatrix first, ref SKMatrix second) { fixed (SKMatrix* result = &target) { fixed (SKMatrix* first2 = &first) { fixed (SKMatrix* second2 = &second) { SkiaApi.sk_matrix_concat(result, first2, second2); } } } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use PreConcat(SKMatrix) instead.")] public unsafe static void PreConcat(ref SKMatrix target, SKMatrix matrix) { fixed (SKMatrix* result = &target) { SkiaApi.sk_matrix_pre_concat(result, &matrix); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use PreConcat(SKMatrix) instead.")] public unsafe static void PreConcat(ref SKMatrix target, ref SKMatrix matrix) { fixed (SKMatrix* result = &target) { fixed (SKMatrix* matrix2 = &matrix) { SkiaApi.sk_matrix_pre_concat(result, matrix2); } } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use PostConcat(SKMatrix) instead.")] public unsafe static void PostConcat(ref SKMatrix target, SKMatrix matrix) { fixed (SKMatrix* result = &target) { SkiaApi.sk_matrix_post_concat(result, &matrix); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use PostConcat(SKMatrix) instead.")] public unsafe static void PostConcat(ref SKMatrix target, ref SKMatrix matrix) { fixed (SKMatrix* result = &target) { fixed (SKMatrix* matrix2 = &matrix) { SkiaApi.sk_matrix_post_concat(result, matrix2); } } } public unsafe readonly SKRect MapRect(SKRect source) { SKRect result = default(SKRect); fixed (SKMatrix* matrix = &this) { SkiaApi.sk_matrix_map_rect(matrix, &result, &source); } return result; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MapRect(SKRect) instead.")] public unsafe static void MapRect(ref SKMatrix matrix, out SKRect dest, ref SKRect source) { fixed (SKMatrix* matrix2 = &matrix) { fixed (SKRect* dest2 = &dest) { fixed (SKRect* source2 = &source) { SkiaApi.sk_matrix_map_rect(matrix2, dest2, source2); } } } } public readonly SKPoint MapPoint(SKPoint point) { return MapPoint(point.X, point.Y); } public unsafe readonly SKPoint MapPoint(float x, float y) { SKPoint result = default(SKPoint); fixed (SKMatrix* matrix = &this) { SkiaApi.sk_matrix_map_xy(matrix, x, y, &result); } return result; } public unsafe readonly void MapPoints(SKPoint[] result, SKPoint[] points) { if (result == null) { throw new ArgumentNullException("result"); } if (points == null) { throw new ArgumentNullException("points"); } if (result.Length != points.Length) { throw new ArgumentException("Buffers must be the same size."); } fixed (SKMatrix* matrix = &this) { fixed (SKPoint* dst = result) { fixed (SKPoint* src = points) { SkiaApi.sk_matrix_map_points(matrix, dst, src, result.Length); } } } } public readonly SKPoint[] MapPoints(SKPoint[] points) { if (points == null) { throw new ArgumentNullException("points"); } SKPoint[] result = new SKPoint[points.Length]; MapPoints(result, points); return result; } public readonly SKPoint MapVector(SKPoint vector) { return MapVector(vector.X, vector.Y); } public unsafe readonly SKPoint MapVector(float x, float y) { SKPoint result = default(SKPoint); fixed (SKMatrix* matrix = &this) { SkiaApi.sk_matrix_map_vector(matrix, x, y, &result); } return result; } public unsafe readonly void MapVectors(SKPoint[] result, SKPoint[] vectors) { if (result == null) { throw new ArgumentNullException("result"); } if (vectors == null) { throw new ArgumentNullException("vectors"); } if (result.Length != vectors.Length) { throw new ArgumentException("Buffers must be the same size."); } fixed (SKMatrix* matrix = &this) { fixed (SKPoint* dst = result) { fixed (SKPoint* src = vectors) { SkiaApi.sk_matrix_map_vectors(matrix, dst, src, result.Length); } } } } public readonly SKPoint[] MapVectors(SKPoint[] vectors) { if (vectors == null) { throw new ArgumentNullException("vectors"); } SKPoint[] result = new SKPoint[vectors.Length]; MapVectors(result, vectors); return result; } public unsafe readonly float MapRadius(float radius) { fixed (SKMatrix* matrix = &this) { return SkiaApi.sk_matrix_map_radius(matrix, radius); } } private static void SetSinCos(ref SKMatrix matrix, float sin, float cos) { matrix.scaleX = cos; matrix.skewX = 0f - sin; matrix.transX = 0f; matrix.skewY = sin; matrix.scaleY = cos; matrix.transY = 0f; matrix.persp0 = 0f; matrix.persp1 = 0f; matrix.persp2 = 1f; } private static void SetSinCos(ref SKMatrix matrix, float sin, float cos, float pivotx, float pivoty) { float c = 1f - cos; matrix.scaleX = cos; matrix.skewX = 0f - sin; matrix.transX = Dot(sin, pivoty, c, pivotx); matrix.skewY = sin; matrix.scaleY = cos; matrix.transY = Dot(0f - sin, pivotx, c, pivoty); matrix.persp0 = 0f; matrix.persp1 = 0f; matrix.persp2 = 1f; } private static float Dot(float a, float b, float c, float d) { return a * b + c * d; } private static float Cross(float a, float b, float c, float d) { return a * b - c * d; } } public struct SKRotationScaleMatrix : IEquatable { private float fSCos; private float fSSin; private float fTX; private float fTY; public static readonly SKRotationScaleMatrix Empty; public static readonly SKRotationScaleMatrix Identity = new SKRotationScaleMatrix(1f, 0f, 0f, 0f); public float SCos { readonly get { return fSCos; } set { fSCos = value; } } public float SSin { readonly get { return fSSin; } set { fSSin = value; } } public float TX { readonly get { return fTX; } set { fTX = value; } } public float TY { readonly get { return fTY; } set { fTY = value; } } public readonly bool Equals(SKRotationScaleMatrix obj) { if (fSCos == obj.fSCos && fSSin == obj.fSSin && fTX == obj.fTX) { return fTY == obj.fTY; } return false; } public override readonly bool Equals(object obj) { if (obj is SKRotationScaleMatrix obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKRotationScaleMatrix left, SKRotationScaleMatrix right) { return left.Equals(right); } public static bool operator !=(SKRotationScaleMatrix left, SKRotationScaleMatrix right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(fSCos); hashCode.Add(fSSin); hashCode.Add(fTX); hashCode.Add(fTY); return hashCode.ToHashCode(); } public SKRotationScaleMatrix(float scos, float ssin, float tx, float ty) { fSCos = scos; fSSin = ssin; fTX = tx; fTY = ty; } public readonly SKMatrix ToMatrix() { return new SKMatrix(fSCos, 0f - fSSin, fTX, fSSin, fSCos, fTY, 0f, 0f, 1f); } public static SKRotationScaleMatrix CreateDegrees(float scale, float degrees, float tx, float ty, float anchorX, float anchorY) { return Create(scale, degrees * (MathF.PI / 180f), tx, ty, anchorX, anchorY); } public static SKRotationScaleMatrix Create(float scale, float radians, float tx, float ty, float anchorX, float anchorY) { float num = (float)Math.Sin(radians) * scale; float num2 = (float)Math.Cos(radians) * scale; float tx2 = tx + (0f - num2) * anchorX + num * anchorY; float ty2 = ty + (0f - num) * anchorX - num2 * anchorY; return new SKRotationScaleMatrix(num2, num, tx2, ty2); } public static SKRotationScaleMatrix CreateIdentity() { return new SKRotationScaleMatrix(1f, 0f, 0f, 0f); } public static SKRotationScaleMatrix CreateTranslation(float x, float y) { return new SKRotationScaleMatrix(1f, 0f, x, y); } public static SKRotationScaleMatrix CreateScale(float s) { return new SKRotationScaleMatrix(s, 0f, 0f, 0f); } public static SKRotationScaleMatrix CreateRotation(float radians, float anchorX, float anchorY) { return Create(1f, radians, 0f, 0f, anchorX, anchorY); } public static SKRotationScaleMatrix CreateRotationDegrees(float degrees, float anchorX, float anchorY) { return CreateDegrees(1f, degrees, 0f, 0f, anchorX, anchorY); } } internal struct SKRunBufferInternal : IEquatable { public unsafe void* glyphs; public unsafe void* pos; public unsafe void* utf8text; public unsafe void* clusters; public unsafe readonly bool Equals(SKRunBufferInternal obj) { if (glyphs == obj.glyphs && pos == obj.pos && utf8text == obj.utf8text) { return clusters == obj.clusters; } return false; } public override readonly bool Equals(object obj) { if (obj is SKRunBufferInternal obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKRunBufferInternal left, SKRunBufferInternal right) { return left.Equals(right); } public static bool operator !=(SKRunBufferInternal left, SKRunBufferInternal right) { return !left.Equals(right); } public unsafe override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(glyphs); hashCode.Add(pos); hashCode.Add(utf8text); hashCode.Add(clusters); return hashCode.ToHashCode(); } } internal enum GRBackendNative { OpenGL, Vulkan, Metal, Direct3D, Dawn } public enum GRSurfaceOrigin { TopLeft, BottomLeft } public enum SKAlphaType { Unknown, Opaque, Premul, Unpremul } [Flags] public enum SKBitmapAllocFlags { None = 0, ZeroPixels = 1 } public enum SKBlendMode { Clear, Src, Dst, SrcOver, DstOver, SrcIn, DstIn, SrcOut, DstOut, SrcATop, DstATop, Xor, Plus, Modulate, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, Multiply, Hue, Saturation, Color, Luminosity } public enum SKBlurStyle { Normal, Solid, Outer, Inner } public enum SKClipOperation { Difference, Intersect } public enum SKCodecResult { Success, IncompleteInput, ErrorInInput, InvalidConversion, InvalidScale, InvalidParameters, InvalidInput, CouldNotRewind, InternalError, Unimplemented } public enum SKCodecScanlineOrder { TopDown, BottomUp } public enum SKZeroInitialized { Yes, No } public enum SKCodecAnimationDisposalMethod { Keep = 1, RestoreBackgroundColor, RestorePrevious } public enum SKColorChannel { R, G, B, A } internal enum SKColorTypeNative { Unknown, Alpha8, Rgb565, Argb4444, Rgba8888, Rgb888x, Bgra8888, Rgba1010102, Bgra1010102, Rgb101010x, Bgr101010x, Gray8, RgbaF16Norm, RgbaF16, RgbaF32, R8g8Unorm, A16Float, R16g16Float, A16Unorm, R16g16Unorm, R16g16b16a16Unorm } [Flags] public enum SKCropRectFlags { HasNone = 0, HasLeft = 1, HasTop = 2, HasWidth = 4, HasHeight = 8, HasAll = 0xF } public enum SKEncodedImageFormat { Bmp, Gif, Ico, Jpeg, Png, Wbmp, Webp, Pkm, Ktx, Astc, Dng, Heif, Avif } public enum SKEncodedOrigin { TopLeft = 1, TopRight = 2, BottomRight = 3, BottomLeft = 4, LeftTop = 5, RightTop = 6, RightBottom = 7, LeftBottom = 8, Default = 1 } public enum SKFilterQuality { None, Low, Medium, High } public enum SKFontEdging { Alias, Antialias, SubpixelAntialias } public enum SKFontHinting { None, Slight, Normal, Full } public enum SKFontStyleSlant { Upright, Italic, Oblique } public enum SKHighContrastConfigInvertStyle { NoInvert, InvertBrightness, InvertLightness } public enum SKImageCachingHint { Allow, Disallow } public enum SKJpegEncoderAlphaOption { Ignore, BlendOnBlack } public enum SKJpegEncoderDownsample { Downsample420, Downsample422, Downsample444 } public enum SKLatticeRectType { Default, Transparent, FixedColor } public enum SKMaskFormat { BW, A8, ThreeD, Argb32, Lcd16, Sdf } [Flags] public enum SKMatrix44TypeMask { Identity = 0, Translate = 1, Scale = 2, Affine = 4, Perspective = 8 } public enum SKPaintStyle { Fill, Stroke, StrokeAndFill } public enum SKPathAddMode { Append, Extend } public enum SKPathArcSize { Small, Large } public enum SKPathDirection { Clockwise, CounterClockwise } public enum SKPath1DPathEffectStyle { Translate, Rotate, Morph } public enum SKTrimPathEffectMode { Normal, Inverted } public enum SKPathFillType { Winding, EvenOdd, InverseWinding, InverseEvenOdd } [Flags] public enum SKPathSegmentMask { Line = 1, Quad = 2, Conic = 4, Cubic = 8 } public enum SKPathVerb { Move, Line, Quad, Conic, Cubic, Close, Done } [Flags] public enum SKPathMeasureMatrixFlags { GetPosition = 1, GetTangent = 2, GetPositionAndTangent = 3 } public enum SKPathOp { Difference, Intersect, Union, Xor, ReverseDifference } public enum SKPixelGeometry { Unknown, RgbHorizontal, BgrHorizontal, RgbVertical, BgrVertical } [Flags] public enum SKPngEncoderFilterFlags { NoFilters = 0, None = 8, Sub = 0x10, Up = 0x20, Avg = 0x40, Paeth = 0x80, AllFilters = 0xF8 } public enum SKPointMode { Points, Lines, Polygon } public enum SKRegionOperation { Difference, Intersect, Union, XOR, ReverseDifference, Replace } public enum SKRoundRectCorner { UpperLeft, UpperRight, LowerRight, LowerLeft } public enum SKRoundRectType { Empty, Rect, Oval, Simple, NinePatch, Complex } public enum SKShaderTileMode { Clamp, Repeat, Mirror, Decal } public enum SKStrokeCap { Butt, Round, Square } public enum SKStrokeJoin { Miter, Round, Bevel } [Flags] public enum SKSurfacePropsFlags { None = 0, UseDeviceIndependentFonts = 1 } public enum SKTextAlign { Left, Center, Right } public enum SKTextEncoding { Utf8, Utf16, Utf32, GlyphId } public enum SKVertexMode { Triangles, TriangleStrip, TriangleFan } public enum SKWebpEncoderCompression { Lossy, Lossless } public static class SkiaSharpVersion { private static readonly Version Zero = new Version(0, 0); private static Version nativeMinimum; private static Version nativeVersion; public static Version NativeMinimum => nativeMinimum ?? (nativeMinimum = new Version(88, 1)); public static Version Native { get { try { return nativeVersion ?? (nativeVersion = new Version(SkiaApi.sk_version_get_milestone(), SkiaApi.sk_version_get_increment())); } catch (EntryPointNotFoundException) { return nativeVersion ?? (nativeVersion = Zero); } } } internal unsafe static string NativeString => Marshal.PtrToStringAnsi((IntPtr)SkiaApi.sk_version_get_string()); public static bool CheckNativeLibraryCompatible(bool throwIfIncompatible = false) { return CheckNativeLibraryCompatible(NativeMinimum, Native, throwIfIncompatible); } internal static bool CheckNativeLibraryCompatible(Version minSupported, Version current, bool throwIfIncompatible = false) { if ((object)minSupported == null) { minSupported = Zero; } if ((object)current == null) { current = Zero; } if (minSupported <= Zero) { return true; } Version version = new Version(minSupported.Major + 1, 0); if (current <= Zero) { if (throwIfIncompatible) { throw new InvalidOperationException("The version of the native libSkiaSharp library is incompatible with this version of SkiaSharp. Supported versions of the native libSkiaSharp library are in the range [" + minSupported.ToString(2) + ", " + version.ToString(2) + ")."); } return false; } bool flag = current < minSupported || current >= version; if (flag && throwIfIncompatible) { throw new InvalidOperationException("The version of the native libSkiaSharp library (" + current.ToString(2) + ") is incompatible with this version of SkiaSharp. Supported versions of the native libSkiaSharp library are in the range [" + minSupported.ToString(2) + ", " + version.ToString(2) + ")."); } return !flag; } } public class SKImage : SKObject, ISKReferenceCounted { public int Width => SkiaApi.sk_image_get_width(Handle); public int Height => SkiaApi.sk_image_get_height(Handle); public uint UniqueId => SkiaApi.sk_image_get_unique_id(Handle); public SKAlphaType AlphaType => SkiaApi.sk_image_get_alpha_type(Handle); public SKColorType ColorType => SkiaApi.sk_image_get_color_type(Handle).FromNative(); public SKColorSpace ColorSpace => SKColorSpace.GetObject(SkiaApi.sk_image_get_colorspace(Handle)); public bool IsAlphaOnly => SkiaApi.sk_image_is_alpha_only(Handle); public SKData EncodedData => SKData.GetObject(SkiaApi.sk_image_ref_encoded(Handle)); public SKImageInfo Info => new SKImageInfo(Width, Height, ColorType, AlphaType, ColorSpace); public bool IsTextureBacked => SkiaApi.sk_image_is_texture_backed(Handle); public bool IsLazyGenerated => SkiaApi.sk_image_is_lazy_generated(Handle); internal SKImage(IntPtr x, bool owns) : base(x, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public unsafe static SKImage Create(SKImageInfo info) { IntPtr addr = Marshal.AllocCoTaskMem(info.BytesSize); using SKPixmap sKPixmap = new SKPixmap(info, addr); return GetObject(SkiaApi.sk_image_new_raster(sKPixmap.Handle, DelegateProxies.SKImageRasterReleaseDelegateProxyForCoTaskMem, null)); } public static SKImage FromPixelCopy(SKImageInfo info, SKStream pixels) { return FromPixelCopy(info, pixels, info.RowBytes); } public static SKImage FromPixelCopy(SKImageInfo info, SKStream pixels, int rowBytes) { if (pixels == null) { throw new ArgumentNullException("pixels"); } using SKData data = SKData.Create(pixels); return FromPixels(info, data, rowBytes); } public static SKImage FromPixelCopy(SKImageInfo info, Stream pixels) { return FromPixelCopy(info, pixels, info.RowBytes); } public static SKImage FromPixelCopy(SKImageInfo info, Stream pixels, int rowBytes) { if (pixels == null) { throw new ArgumentNullException("pixels"); } using SKData data = SKData.Create(pixels); return FromPixels(info, data, rowBytes); } public static SKImage FromPixelCopy(SKImageInfo info, byte[] pixels) { return FromPixelCopy(info, pixels, info.RowBytes); } public static SKImage FromPixelCopy(SKImageInfo info, byte[] pixels, int rowBytes) { if (pixels == null) { throw new ArgumentNullException("pixels"); } using SKData data = SKData.CreateCopy(pixels); return FromPixels(info, data, rowBytes); } public static SKImage FromPixelCopy(SKImageInfo info, IntPtr pixels) { return FromPixelCopy(info, pixels, info.RowBytes); } public unsafe static SKImage FromPixelCopy(SKImageInfo info, IntPtr pixels, int rowBytes) { if (pixels == IntPtr.Zero) { throw new ArgumentNullException("pixels"); } SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return GetObject(SkiaApi.sk_image_new_raster_copy(&sKImageInfoNative, (void*)pixels, (IntPtr)rowBytes)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use FromPixelCopy(SKImageInfo, IntPtr, int) instead.")] public static SKImage FromPixelCopy(SKImageInfo info, IntPtr pixels, int rowBytes, SKColorTable ctable) { return FromPixelCopy(info, pixels, rowBytes); } public static SKImage FromPixelCopy(SKPixmap pixmap) { if (pixmap == null) { throw new ArgumentNullException("pixmap"); } return GetObject(SkiaApi.sk_image_new_raster_copy_with_pixmap(pixmap.Handle)); } public static SKImage FromPixelCopy(SKImageInfo info, ReadOnlySpan pixels) { return FromPixelCopy(info, pixels, info.RowBytes); } public static SKImage FromPixelCopy(SKImageInfo info, ReadOnlySpan pixels, int rowBytes) { if (pixels == null) { throw new ArgumentNullException("pixels"); } using SKData data = SKData.CreateCopy(pixels); return FromPixels(info, data, rowBytes); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromPixels (SKImageInfo, SKData, int) instead.")] public unsafe static SKImage FromPixelData(SKImageInfo info, SKData data, int rowBytes) { if (data == null) { throw new ArgumentNullException("data"); } SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return GetObject(SkiaApi.sk_image_new_raster_data(&sKImageInfoNative, data.Handle, (IntPtr)rowBytes)); } public static SKImage FromPixels(SKImageInfo info, SKData data) { return FromPixels(info, data, info.RowBytes); } public unsafe static SKImage FromPixels(SKImageInfo info, SKData data, int rowBytes) { if (data == null) { throw new ArgumentNullException("data"); } SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return GetObject(SkiaApi.sk_image_new_raster_data(&sKImageInfoNative, data.Handle, (IntPtr)rowBytes)); } public static SKImage FromPixels(SKImageInfo info, IntPtr pixels) { using SKPixmap pixmap = new SKPixmap(info, pixels, info.RowBytes); return FromPixels(pixmap, null, null); } public static SKImage FromPixels(SKImageInfo info, IntPtr pixels, int rowBytes) { using SKPixmap pixmap = new SKPixmap(info, pixels, rowBytes); return FromPixels(pixmap, null, null); } public static SKImage FromPixels(SKPixmap pixmap) { return FromPixels(pixmap, null, null); } public static SKImage FromPixels(SKPixmap pixmap, SKImageRasterReleaseDelegate releaseProc) { return FromPixels(pixmap, releaseProc, null); } public unsafe static SKImage FromPixels(SKPixmap pixmap, SKImageRasterReleaseDelegate releaseProc, object releaseContext) { if (pixmap == null) { throw new ArgumentNullException("pixmap"); } SKImageRasterReleaseDelegate managedDel = ((releaseProc != null && releaseContext != null) ? ((SKImageRasterReleaseDelegate)delegate(IntPtr addr, object _) { releaseProc(addr, releaseContext); }) : releaseProc); GCHandle gch; IntPtr contextPtr; SKImageRasterReleaseProxyDelegate releaseProc2 = DelegateProxies.Create(managedDel, DelegateProxies.SKImageRasterReleaseDelegateProxy, out gch, out contextPtr); return GetObject(SkiaApi.sk_image_new_raster(pixmap.Handle, releaseProc2, (void*)contextPtr)); } public static SKImage FromEncodedData(SKData data, SKRectI subset) { if (data == null) { throw new ArgumentNullException("data"); } return FromEncodedData(data)?.Subset(subset); } public static SKImage FromEncodedData(SKData data) { if (data == null) { throw new ArgumentNullException("data"); } IntPtr handle = SkiaApi.sk_image_new_from_encoded(data.Handle); return GetObject(handle); } public static SKImage FromEncodedData(ReadOnlySpan data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length == 0) { throw new ArgumentException("The data buffer was empty."); } using SKData data2 = SKData.CreateCopy(data); return FromEncodedData(data2); } public static SKImage FromEncodedData(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length == 0) { throw new ArgumentException("The data buffer was empty."); } using SKData data2 = SKData.CreateCopy(data); return FromEncodedData(data2); } public static SKImage FromEncodedData(SKStream data) { if (data == null) { throw new ArgumentNullException("data"); } using SKData sKData = SKData.Create(data); if (sKData == null) { return null; } return FromEncodedData(sKData); } public static SKImage FromEncodedData(Stream data) { if (data == null) { throw new ArgumentNullException("data"); } using SKData sKData = SKData.Create(data); if (sKData == null) { return null; } return FromEncodedData(sKData); } public static SKImage FromEncodedData(string filename) { if (filename == null) { throw new ArgumentNullException("filename"); } using SKData sKData = SKData.Create(filename); if (sKData == null) { return null; } return FromEncodedData(sKData); } public static SKImage FromBitmap(SKBitmap bitmap) { if (bitmap == null) { throw new ArgumentNullException("bitmap"); } SKImage result = GetObject(SkiaApi.sk_image_new_from_bitmap(bitmap.Handle)); GC.KeepAlive(bitmap); return result; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType) instead.")] public static SKImage FromTexture(GRContext context, GRBackendTextureDesc desc) { return FromTexture(context, desc, SKAlphaType.Premul, null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKAlphaType) instead.")] public static SKImage FromTexture(GRContext context, GRBackendTextureDesc desc, SKAlphaType alpha) { return FromTexture(context, desc, alpha, null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKAlphaType, SKColorSpace, SKImageTextureReleaseDelegate) instead.")] public static SKImage FromTexture(GRContext context, GRBackendTextureDesc desc, SKAlphaType alpha, SKImageTextureReleaseDelegate releaseProc) { return FromTexture(context, desc, alpha, releaseProc, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKAlphaType, SKColorSpace, SKImageTextureReleaseDelegate, object) instead.")] public static SKImage FromTexture(GRContext context, GRBackendTextureDesc desc, SKAlphaType alpha, SKImageTextureReleaseDelegate releaseProc, object releaseContext) { if (context == null) { throw new ArgumentNullException("context"); } GRBackendTexture texture = new GRBackendTexture(desc); return FromTexture(context, texture, desc.Origin, desc.Config.ToColorType(), alpha, null, releaseProc, releaseContext); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType) instead.")] public static SKImage FromTexture(GRContext context, GRGlBackendTextureDesc desc) { return FromTexture(context, desc, SKAlphaType.Premul, null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKAlphaType) instead.")] public static SKImage FromTexture(GRContext context, GRGlBackendTextureDesc desc, SKAlphaType alpha) { return FromTexture(context, desc, alpha, null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKAlphaType, SKColorSpace, SKImageTextureReleaseDelegate) instead.")] public static SKImage FromTexture(GRContext context, GRGlBackendTextureDesc desc, SKAlphaType alpha, SKImageTextureReleaseDelegate releaseProc) { return FromTexture(context, desc, alpha, releaseProc, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKAlphaType, SKColorSpace, SKImageTextureReleaseDelegate, object) instead.")] public static SKImage FromTexture(GRContext context, GRGlBackendTextureDesc desc, SKAlphaType alpha, SKImageTextureReleaseDelegate releaseProc, object releaseContext) { GRBackendTexture texture = new GRBackendTexture(desc); return FromTexture(context, texture, desc.Origin, desc.Config.ToColorType(), alpha, null, releaseProc, releaseContext); } public static SKImage FromTexture(GRContext context, GRBackendTexture texture, SKColorType colorType) { return FromTexture((GRRecordingContext)context, texture, colorType); } public static SKImage FromTexture(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) { return FromTexture((GRRecordingContext)context, texture, origin, colorType); } public static SKImage FromTexture(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha) { return FromTexture((GRRecordingContext)context, texture, origin, colorType, alpha); } public static SKImage FromTexture(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha, SKColorSpace colorspace) { return FromTexture((GRRecordingContext)context, texture, origin, colorType, alpha, colorspace); } public static SKImage FromTexture(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha, SKColorSpace colorspace, SKImageTextureReleaseDelegate releaseProc) { return FromTexture((GRRecordingContext)context, texture, origin, colorType, alpha, colorspace, releaseProc); } public static SKImage FromTexture(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha, SKColorSpace colorspace, SKImageTextureReleaseDelegate releaseProc, object releaseContext) { return FromTexture((GRRecordingContext)context, texture, origin, colorType, alpha, colorspace, releaseProc, releaseContext); } public static SKImage FromTexture(GRRecordingContext context, GRBackendTexture texture, SKColorType colorType) { return FromTexture(context, texture, GRSurfaceOrigin.BottomLeft, colorType, SKAlphaType.Premul, null, null, null); } public static SKImage FromTexture(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) { return FromTexture(context, texture, origin, colorType, SKAlphaType.Premul, null, null, null); } public static SKImage FromTexture(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha) { return FromTexture(context, texture, origin, colorType, alpha, null, null, null); } public static SKImage FromTexture(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha, SKColorSpace colorspace) { return FromTexture(context, texture, origin, colorType, alpha, colorspace, null, null); } public static SKImage FromTexture(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha, SKColorSpace colorspace, SKImageTextureReleaseDelegate releaseProc) { return FromTexture(context, texture, origin, colorType, alpha, colorspace, releaseProc, null); } public unsafe static SKImage FromTexture(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha, SKColorSpace colorspace, SKImageTextureReleaseDelegate releaseProc, object releaseContext) { if (context == null) { throw new ArgumentNullException("context"); } if (texture == null) { throw new ArgumentNullException("texture"); } IntPtr colorSpace = colorspace?.Handle ?? IntPtr.Zero; SKImageTextureReleaseDelegate managedDel = ((releaseProc != null && releaseContext != null) ? ((SKImageTextureReleaseDelegate)delegate { releaseProc(releaseContext); }) : releaseProc); GCHandle gch; IntPtr contextPtr; SKImageTextureReleaseProxyDelegate releaseProc2 = DelegateProxies.Create(managedDel, DelegateProxies.SKImageTextureReleaseDelegateProxy, out gch, out contextPtr); return GetObject(SkiaApi.sk_image_new_from_texture(context.Handle, texture.Handle, origin, colorType.ToNative(), alpha, colorSpace, releaseProc2, (void*)contextPtr)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromAdoptedTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType) instead.")] public static SKImage FromAdoptedTexture(GRContext context, GRBackendTextureDesc desc) { return FromAdoptedTexture(context, desc, SKAlphaType.Premul); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromAdoptedTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKAlphaType) instead.")] public static SKImage FromAdoptedTexture(GRContext context, GRBackendTextureDesc desc, SKAlphaType alpha) { GRBackendTexture texture = new GRBackendTexture(desc); return FromAdoptedTexture(context, texture, desc.Origin, desc.Config.ToColorType(), alpha, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromAdoptedTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType) instead.")] public static SKImage FromAdoptedTexture(GRContext context, GRGlBackendTextureDesc desc) { return FromAdoptedTexture(context, desc, SKAlphaType.Premul); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromAdoptedTexture(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKAlphaType) instead.")] public static SKImage FromAdoptedTexture(GRContext context, GRGlBackendTextureDesc desc, SKAlphaType alpha) { GRBackendTexture texture = new GRBackendTexture(desc); return FromAdoptedTexture(context, texture, desc.Origin, desc.Config.ToColorType(), alpha, null); } public static SKImage FromAdoptedTexture(GRContext context, GRBackendTexture texture, SKColorType colorType) { return FromAdoptedTexture((GRRecordingContext)context, texture, colorType); } public static SKImage FromAdoptedTexture(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) { return FromAdoptedTexture((GRRecordingContext)context, texture, origin, colorType); } public static SKImage FromAdoptedTexture(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha) { return FromAdoptedTexture((GRRecordingContext)context, texture, origin, colorType, alpha); } public static SKImage FromAdoptedTexture(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha, SKColorSpace colorspace) { return FromAdoptedTexture((GRRecordingContext)context, texture, origin, colorType, alpha, colorspace); } public static SKImage FromAdoptedTexture(GRRecordingContext context, GRBackendTexture texture, SKColorType colorType) { return FromAdoptedTexture(context, texture, GRSurfaceOrigin.BottomLeft, colorType, SKAlphaType.Premul, null); } public static SKImage FromAdoptedTexture(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) { return FromAdoptedTexture(context, texture, origin, colorType, SKAlphaType.Premul, null); } public static SKImage FromAdoptedTexture(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha) { return FromAdoptedTexture(context, texture, origin, colorType, alpha, null); } public static SKImage FromAdoptedTexture(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKAlphaType alpha, SKColorSpace colorspace) { if (context == null) { throw new ArgumentNullException("context"); } if (texture == null) { throw new ArgumentNullException("texture"); } IntPtr colorSpace = colorspace?.Handle ?? IntPtr.Zero; return GetObject(SkiaApi.sk_image_new_from_adopted_texture(context.Handle, texture.Handle, origin, colorType.ToNative(), alpha, colorSpace)); } public unsafe static SKImage FromPicture(SKPicture picture, SKSizeI dimensions) { return FromPicture(picture, dimensions, null, null); } public unsafe static SKImage FromPicture(SKPicture picture, SKSizeI dimensions, SKMatrix matrix) { return FromPicture(picture, dimensions, &matrix, null); } public unsafe static SKImage FromPicture(SKPicture picture, SKSizeI dimensions, SKPaint paint) { return FromPicture(picture, dimensions, null, paint); } public unsafe static SKImage FromPicture(SKPicture picture, SKSizeI dimensions, SKMatrix matrix, SKPaint paint) { return FromPicture(picture, dimensions, &matrix, paint); } private unsafe static SKImage FromPicture(SKPicture picture, SKSizeI dimensions, SKMatrix* matrix, SKPaint paint) { if (picture == null) { throw new ArgumentNullException("picture"); } IntPtr paint2 = paint?.Handle ?? IntPtr.Zero; return GetObject(SkiaApi.sk_image_new_from_picture(picture.Handle, &dimensions, matrix, paint2)); } public SKData Encode() { return SKData.GetObject(SkiaApi.sk_image_encode(Handle)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public SKData Encode(SKPixelSerializer serializer) { if (serializer == null) { throw new ArgumentNullException("serializer"); } SKData encodedData = EncodedData; if (encodedData != null) { if (serializer.UseEncodedData(encodedData.Data, (ulong)encodedData.Size)) { return encodedData; } encodedData.Dispose(); encodedData = null; } if (!IsTextureBacked) { using (SKPixmap pixmap = PeekPixels()) { return serializer.Encode(pixmap); } } if (IsTextureBacked) { SKImageInfo info = new SKImageInfo(Width, Height, ColorType, AlphaType, ColorSpace); using SKBitmap sKBitmap = new SKBitmap(info); using SKPixmap sKPixmap = sKBitmap.PeekPixels(); if (sKPixmap != null && ReadPixels(sKPixmap, 0, 0)) { return serializer.Encode(sKPixmap); } } return null; } public SKData Encode(SKEncodedImageFormat format, int quality) { return SKData.GetObject(SkiaApi.sk_image_encode_specific(Handle, format, quality)); } public SKShader ToShader() { return ToShader(SKShaderTileMode.Clamp, SKShaderTileMode.Clamp); } public unsafe SKShader ToShader(SKShaderTileMode tileX, SKShaderTileMode tileY) { return SKShader.GetObject(SkiaApi.sk_image_make_shader(Handle, tileX, tileY, null)); } public unsafe SKShader ToShader(SKShaderTileMode tileX, SKShaderTileMode tileY, SKMatrix localMatrix) { return SKShader.GetObject(SkiaApi.sk_image_make_shader(Handle, tileX, tileY, &localMatrix)); } public bool PeekPixels(SKPixmap pixmap) { if (pixmap == null) { throw new ArgumentNullException("pixmap"); } bool flag = SkiaApi.sk_image_peek_pixels(Handle, pixmap.Handle); if (flag) { pixmap.pixelSource = this; } return flag; } public SKPixmap PeekPixels() { SKPixmap sKPixmap = new SKPixmap(); if (!PeekPixels(sKPixmap)) { sKPixmap.Dispose(); sKPixmap = null; } return sKPixmap; } public bool IsValid(GRContext context) { return IsValid((GRRecordingContext)context); } public bool IsValid(GRRecordingContext context) { return SkiaApi.sk_image_is_valid(Handle, context?.Handle ?? IntPtr.Zero); } public bool ReadPixels(SKImageInfo dstInfo, IntPtr dstPixels) { return ReadPixels(dstInfo, dstPixels, dstInfo.RowBytes, 0, 0, SKImageCachingHint.Allow); } public bool ReadPixels(SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes) { return ReadPixels(dstInfo, dstPixels, dstRowBytes, 0, 0, SKImageCachingHint.Allow); } public bool ReadPixels(SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY) { return ReadPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY, SKImageCachingHint.Allow); } public unsafe bool ReadPixels(SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY, SKImageCachingHint cachingHint) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref dstInfo); bool result = SkiaApi.sk_image_read_pixels(Handle, &sKImageInfoNative, (void*)dstPixels, (IntPtr)dstRowBytes, srcX, srcY, cachingHint); GC.KeepAlive(this); return result; } public bool ReadPixels(SKPixmap pixmap) { return ReadPixels(pixmap, 0, 0, SKImageCachingHint.Allow); } public bool ReadPixels(SKPixmap pixmap, int srcX, int srcY) { return ReadPixels(pixmap, srcX, srcY, SKImageCachingHint.Allow); } public bool ReadPixels(SKPixmap pixmap, int srcX, int srcY, SKImageCachingHint cachingHint) { if (pixmap == null) { throw new ArgumentNullException("pixmap"); } bool result = SkiaApi.sk_image_read_pixels_into_pixmap(Handle, pixmap.Handle, srcX, srcY, cachingHint); GC.KeepAlive(this); return result; } public bool ScalePixels(SKPixmap dst, SKFilterQuality quality) { return ScalePixels(dst, quality, SKImageCachingHint.Allow); } public bool ScalePixels(SKPixmap dst, SKFilterQuality quality, SKImageCachingHint cachingHint) { if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_image_scale_pixels(Handle, dst.Handle, quality, cachingHint); } public unsafe SKImage Subset(SKRectI subset) { return GetObject(SkiaApi.sk_image_make_subset(Handle, &subset)); } public SKImage ToRasterImage() { return ToRasterImage(ensurePixelData: false); } public SKImage ToRasterImage(bool ensurePixelData) { if (!ensurePixelData) { return GetObject(SkiaApi.sk_image_make_non_texture_image(Handle)); } return GetObject(SkiaApi.sk_image_make_raster_image(Handle)); } public SKImage ToTextureImage(GRContext context) { return ToTextureImage(context, mipmapped: false); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ToTextureImage(GRContext) instead.")] public SKImage ToTextureImage(GRContext context, SKColorSpace colorspace) { return ToTextureImage(context, mipmapped: false); } public SKImage ToTextureImage(GRContext context, bool mipmapped) { if (context == null) { throw new ArgumentNullException("context"); } return GetObject(SkiaApi.sk_image_make_texture_image(Handle, context.Handle, mipmapped)); } public SKImage ApplyImageFilter(SKImageFilter filter, SKRectI subset, SKRectI clipBounds, out SKRectI outSubset, out SKPoint outOffset) { SKPointI outOffset2; SKImage result = ApplyImageFilter(filter, subset, clipBounds, out outSubset, out outOffset2); outOffset = outOffset2; return result; } public unsafe SKImage ApplyImageFilter(SKImageFilter filter, SKRectI subset, SKRectI clipBounds, out SKRectI outSubset, out SKPointI outOffset) { if (filter == null) { throw new ArgumentNullException("filter"); } fixed (SKRectI* outSubset2 = &outSubset) { fixed (SKPointI* outOffset2 = &outOffset) { return GetObject(SkiaApi.sk_image_make_with_filter_legacy(Handle, filter.Handle, &subset, &clipBounds, outSubset2, outOffset2)); } } } public SKImage ApplyImageFilter(GRContext context, SKImageFilter filter, SKRectI subset, SKRectI clipBounds, out SKRectI outSubset, out SKPointI outOffset) { return ApplyImageFilter((GRRecordingContext)context, filter, subset, clipBounds, out outSubset, out outOffset); } public unsafe SKImage ApplyImageFilter(GRRecordingContext context, SKImageFilter filter, SKRectI subset, SKRectI clipBounds, out SKRectI outSubset, out SKPointI outOffset) { if (filter == null) { throw new ArgumentNullException("filter"); } fixed (SKRectI* outSubset2 = &outSubset) { fixed (SKPointI* outOffset2 = &outOffset) { return GetObject(SkiaApi.sk_image_make_with_filter(Handle, context?.Handle ?? IntPtr.Zero, filter.Handle, &subset, &clipBounds, outSubset2, outOffset2)); } } } internal static SKImage GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKImage(h, o)); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKColorChannel instead.")] public enum SKDisplacementMapEffectChannelSelectorType { Unknown, R, G, B, A } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateDropShadow or CreateDropShadowOnly instead.")] public enum SKDropShadowImageFilterShadowMode { DrawShadowAndForeground, DrawShadowOnly } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SKShaderTileMode instead.")] public enum SKMatrixConvolutionTileMode { Clamp, Repeat, ClampToBlack } public class SKImageFilter : SKObject, ISKReferenceCounted { public class CropRect : SKObject { public unsafe SKRect Rect { get { SKRect result = default(SKRect); SkiaApi.sk_imagefilter_croprect_get_rect(Handle, &result); return result; } } public SKCropRectFlags Flags => (SKCropRectFlags)SkiaApi.sk_imagefilter_croprect_get_flags(Handle); internal CropRect(IntPtr handle, bool owns) : base(handle, owns) { } public CropRect() : this(SkiaApi.sk_imagefilter_croprect_new(), owns: true) { } public unsafe CropRect(SKRect rect, SKCropRectFlags flags = SKCropRectFlags.HasAll) : this(SkiaApi.sk_imagefilter_croprect_new_with_rect(&rect, (uint)flags), owns: true) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_imagefilter_croprect_destructor(Handle); } } internal SKImageFilter(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public unsafe static SKImageFilter CreateMatrix(SKMatrix matrix, SKFilterQuality quality, SKImageFilter input = null) { return GetObject(SkiaApi.sk_imagefilter_new_matrix(&matrix, quality, input?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateAlphaThreshold(SKRectI region, float innerThreshold, float outerThreshold, SKImageFilter input = null) { SKRegion sKRegion = new SKRegion(); sKRegion.SetRect(region); return CreateAlphaThreshold(sKRegion, innerThreshold, outerThreshold, input); } public static SKImageFilter CreateAlphaThreshold(SKRegion region, float innerThreshold, float outerThreshold, SKImageFilter input = null) { if (region == null) { throw new ArgumentNullException("region"); } return GetObject(SkiaApi.sk_imagefilter_new_alpha_threshold(region.Handle, innerThreshold, outerThreshold, input?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateBlur(float sigmaX, float sigmaY, SKImageFilter input = null, CropRect cropRect = null) { return CreateBlur(sigmaX, sigmaY, SKShaderTileMode.Decal, input, cropRect); } public static SKImageFilter CreateBlur(float sigmaX, float sigmaY, SKShaderTileMode tileMode, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_blur(sigmaX, sigmaY, tileMode, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateColorFilter(SKColorFilter cf, SKImageFilter input = null, CropRect cropRect = null) { if (cf == null) { throw new ArgumentNullException("cf"); } return GetObject(SkiaApi.sk_imagefilter_new_color_filter(cf.Handle, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateCompose(SKImageFilter outer, SKImageFilter inner) { if (outer == null) { throw new ArgumentNullException("outer"); } if (inner == null) { throw new ArgumentNullException("inner"); } return GetObject(SkiaApi.sk_imagefilter_new_compose(outer.Handle, inner.Handle)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateDisplacementMapEffect(SKColorChannel, SKColorChannel, float, SKImageFilter, SKImageFilter, SKImageFilter.CropRect) instead.")] public static SKImageFilter CreateDisplacementMapEffect(SKDisplacementMapEffectChannelSelectorType xChannelSelector, SKDisplacementMapEffectChannelSelectorType yChannelSelector, float scale, SKImageFilter displacement, SKImageFilter input = null, CropRect cropRect = null) { return CreateDisplacementMapEffect(xChannelSelector.ToColorChannel(), yChannelSelector.ToColorChannel(), scale, displacement, input, cropRect); } public static SKImageFilter CreateDisplacementMapEffect(SKColorChannel xChannelSelector, SKColorChannel yChannelSelector, float scale, SKImageFilter displacement, SKImageFilter input = null, CropRect cropRect = null) { if (displacement == null) { throw new ArgumentNullException("displacement"); } return GetObject(SkiaApi.sk_imagefilter_new_displacement_map_effect(xChannelSelector, yChannelSelector, scale, displacement.Handle, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateDropShadow or CreateDropShadowOnly instead.")] public static SKImageFilter CreateDropShadow(float dx, float dy, float sigmaX, float sigmaY, SKColor color, SKDropShadowImageFilterShadowMode shadowMode, SKImageFilter input = null, CropRect cropRect = null) { if (shadowMode != SKDropShadowImageFilterShadowMode.DrawShadowOnly) { return CreateDropShadow(dx, dy, sigmaX, sigmaY, color, input, cropRect); } return CreateDropShadowOnly(dx, dy, sigmaX, sigmaY, color, input, cropRect); } public static SKImageFilter CreateDropShadow(float dx, float dy, float sigmaX, float sigmaY, SKColor color, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_drop_shadow(dx, dy, sigmaX, sigmaY, (uint)color, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateDropShadowOnly(float dx, float dy, float sigmaX, float sigmaY, SKColor color, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_drop_shadow_only(dx, dy, sigmaX, sigmaY, (uint)color, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public unsafe static SKImageFilter CreateDistantLitDiffuse(SKPoint3 direction, SKColor lightColor, float surfaceScale, float kd, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_distant_lit_diffuse(&direction, (uint)lightColor, surfaceScale, kd, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public unsafe static SKImageFilter CreatePointLitDiffuse(SKPoint3 location, SKColor lightColor, float surfaceScale, float kd, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_point_lit_diffuse(&location, (uint)lightColor, surfaceScale, kd, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public unsafe static SKImageFilter CreateSpotLitDiffuse(SKPoint3 location, SKPoint3 target, float specularExponent, float cutoffAngle, SKColor lightColor, float surfaceScale, float kd, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_spot_lit_diffuse(&location, &target, specularExponent, cutoffAngle, (uint)lightColor, surfaceScale, kd, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public unsafe static SKImageFilter CreateDistantLitSpecular(SKPoint3 direction, SKColor lightColor, float surfaceScale, float ks, float shininess, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_distant_lit_specular(&direction, (uint)lightColor, surfaceScale, ks, shininess, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public unsafe static SKImageFilter CreatePointLitSpecular(SKPoint3 location, SKColor lightColor, float surfaceScale, float ks, float shininess, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_point_lit_specular(&location, (uint)lightColor, surfaceScale, ks, shininess, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public unsafe static SKImageFilter CreateSpotLitSpecular(SKPoint3 location, SKPoint3 target, float specularExponent, float cutoffAngle, SKColor lightColor, float surfaceScale, float ks, float shininess, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_spot_lit_specular(&location, &target, specularExponent, cutoffAngle, (uint)lightColor, surfaceScale, ks, shininess, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public unsafe static SKImageFilter CreateMagnifier(SKRect src, float inset, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_magnifier(&src, inset, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateMatrixConvolution(SKSizeI, float[], float, float, SKPointI, SKShaderTileMode, bool, SKImageFilter, SKImageFilter.CropRect) instead.")] public static SKImageFilter CreateMatrixConvolution(SKSizeI kernelSize, float[] kernel, float gain, float bias, SKPointI kernelOffset, SKMatrixConvolutionTileMode tileMode, bool convolveAlpha, SKImageFilter input = null, CropRect cropRect = null) { return CreateMatrixConvolution(kernelSize, kernel, gain, bias, kernelOffset, tileMode.ToShaderTileMode(), convolveAlpha, input, cropRect); } public unsafe static SKImageFilter CreateMatrixConvolution(SKSizeI kernelSize, float[] kernel, float gain, float bias, SKPointI kernelOffset, SKShaderTileMode tileMode, bool convolveAlpha, SKImageFilter input = null, CropRect cropRect = null) { if (kernel == null) { throw new ArgumentNullException("kernel"); } if (kernel.Length != kernelSize.Width * kernelSize.Height) { throw new ArgumentException("Kernel length must match the dimensions of the kernel size (Width * Height).", "kernel"); } fixed (float* kernel2 = kernel) { return GetObject(SkiaApi.sk_imagefilter_new_matrix_convolution(&kernelSize, kernel2, gain, bias, &kernelOffset, tileMode, convolveAlpha, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateMerge(SKImageFilter, SKImageFilter, SKImageFilter.CropRect) instead.")] public static SKImageFilter CreateMerge(SKImageFilter first, SKImageFilter second, SKBlendMode mode, CropRect cropRect = null) { return CreateMerge(new SKImageFilter[2] { first, second }, cropRect); } public static SKImageFilter CreateMerge(SKImageFilter first, SKImageFilter second, CropRect cropRect = null) { return CreateMerge(new SKImageFilter[2] { first, second }, cropRect); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateMerge(SKImageFilter[], SKImageFilter.CropRect) instead.")] public static SKImageFilter CreateMerge(SKImageFilter[] filters, SKBlendMode[] modes, CropRect cropRect = null) { return CreateMerge(filters, cropRect); } public unsafe static SKImageFilter CreateMerge(SKImageFilter[] filters, CropRect cropRect = null) { if (filters == null) { throw new ArgumentNullException("filters"); } IntPtr[] array = new IntPtr[filters.Length]; for (int i = 0; i < filters.Length; i++) { array[i] = filters[i]?.Handle ?? IntPtr.Zero; } fixed (IntPtr* filters2 = array) { return GetObject(SkiaApi.sk_imagefilter_new_merge(filters2, filters.Length, cropRect?.Handle ?? IntPtr.Zero)); } } public static SKImageFilter CreateDilate(int radiusX, int radiusY, SKImageFilter input = null, CropRect cropRect = null) { return CreateDilate((float)radiusX, (float)radiusY, input, cropRect); } public static SKImageFilter CreateDilate(float radiusX, float radiusY, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_dilate(radiusX, radiusY, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateErode(int radiusX, int radiusY, SKImageFilter input = null, CropRect cropRect = null) { return CreateErode((float)radiusX, (float)radiusY, input, cropRect); } public static SKImageFilter CreateErode(float radiusX, float radiusY, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_erode(radiusX, radiusY, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateOffset(float dx, float dy, SKImageFilter input = null, CropRect cropRect = null) { return GetObject(SkiaApi.sk_imagefilter_new_offset(dx, dy, input?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreatePicture(SKPicture picture) { if (picture == null) { throw new ArgumentNullException("picture"); } return GetObject(SkiaApi.sk_imagefilter_new_picture(picture.Handle)); } public unsafe static SKImageFilter CreatePicture(SKPicture picture, SKRect cropRect) { if (picture == null) { throw new ArgumentNullException("picture"); } return GetObject(SkiaApi.sk_imagefilter_new_picture_with_croprect(picture.Handle, &cropRect)); } public unsafe static SKImageFilter CreateTile(SKRect src, SKRect dst, SKImageFilter input) { if (input == null) { throw new ArgumentNullException("input"); } return GetObject(SkiaApi.sk_imagefilter_new_tile(&src, &dst, input.Handle)); } public static SKImageFilter CreateBlendMode(SKBlendMode mode, SKImageFilter background, SKImageFilter foreground = null, CropRect cropRect = null) { if (background == null) { throw new ArgumentNullException("background"); } return GetObject(SkiaApi.sk_imagefilter_new_xfermode(mode, background.Handle, foreground?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateArithmetic(float k1, float k2, float k3, float k4, bool enforcePMColor, SKImageFilter background, SKImageFilter foreground = null, CropRect cropRect = null) { if (background == null) { throw new ArgumentNullException("background"); } return GetObject(SkiaApi.sk_imagefilter_new_arithmetic(k1, k2, k3, k4, enforcePMColor, background.Handle, foreground?.Handle ?? IntPtr.Zero, cropRect?.Handle ?? IntPtr.Zero)); } public static SKImageFilter CreateImage(SKImage image) { if (image == null) { throw new ArgumentNullException("image"); } return GetObject(SkiaApi.sk_imagefilter_new_image_source_default(image.Handle)); } public unsafe static SKImageFilter CreateImage(SKImage image, SKRect src, SKRect dst, SKFilterQuality filterQuality) { if (image == null) { throw new ArgumentNullException("image"); } return GetObject(SkiaApi.sk_imagefilter_new_image_source(image.Handle, &src, &dst, filterQuality)); } public static SKImageFilter CreatePaint(SKPaint paint, CropRect cropRect = null) { if (paint == null) { throw new ArgumentNullException("paint"); } return GetObject(SkiaApi.sk_imagefilter_new_paint(paint.Handle, cropRect?.Handle ?? IntPtr.Zero)); } internal static SKImageFilter GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKImageFilter(h, o)); } } public struct SKImageInfo : IEquatable { public static readonly SKImageInfo Empty; public static readonly SKColorType PlatformColorType; public static readonly int PlatformColorAlphaShift; public static readonly int PlatformColorRedShift; public static readonly int PlatformColorGreenShift; public static readonly int PlatformColorBlueShift; public int Width { get; set; } public int Height { get; set; } public SKColorType ColorType { get; set; } public SKAlphaType AlphaType { get; set; } public SKColorSpace ColorSpace { get; set; } public readonly int BytesPerPixel => ColorType.GetBytesPerPixel(); public readonly int BitsPerPixel => BytesPerPixel * 8; public readonly int BytesSize => Width * Height * BytesPerPixel; public readonly long BytesSize64 => (long)Width * (long)Height * BytesPerPixel; public readonly int RowBytes => Width * BytesPerPixel; public readonly long RowBytes64 => (long)Width * (long)BytesPerPixel; public readonly bool IsEmpty { get { if (Width > 0) { return Height <= 0; } return true; } } public readonly bool IsOpaque => AlphaType == SKAlphaType.Opaque; public readonly SKSizeI Size => new SKSizeI(Width, Height); public readonly SKRectI Rect => SKRectI.Create(Width, Height); unsafe static SKImageInfo() { PlatformColorType = SkiaApi.sk_colortype_get_default_8888().FromNative(); fixed (int* platformColorAlphaShift = &PlatformColorAlphaShift) { fixed (int* platformColorRedShift = &PlatformColorRedShift) { fixed (int* platformColorGreenShift = &PlatformColorGreenShift) { fixed (int* platformColorBlueShift = &PlatformColorBlueShift) { SkiaApi.sk_color_get_bit_shift(platformColorAlphaShift, platformColorRedShift, platformColorGreenShift, platformColorBlueShift); } } } } } public SKImageInfo(int width, int height) { Width = width; Height = height; ColorType = PlatformColorType; AlphaType = SKAlphaType.Premul; ColorSpace = null; } public SKImageInfo(int width, int height, SKColorType colorType) { Width = width; Height = height; ColorType = colorType; AlphaType = SKAlphaType.Premul; ColorSpace = null; } public SKImageInfo(int width, int height, SKColorType colorType, SKAlphaType alphaType) { Width = width; Height = height; ColorType = colorType; AlphaType = alphaType; ColorSpace = null; } public SKImageInfo(int width, int height, SKColorType colorType, SKAlphaType alphaType, SKColorSpace colorspace) { Width = width; Height = height; ColorType = colorType; AlphaType = alphaType; ColorSpace = colorspace; } public readonly SKImageInfo WithSize(SKSizeI size) { return WithSize(size.Width, size.Height); } public readonly SKImageInfo WithSize(int width, int height) { SKImageInfo result = this; result.Width = width; result.Height = height; return result; } public readonly SKImageInfo WithColorType(SKColorType newColorType) { SKImageInfo result = this; result.ColorType = newColorType; return result; } public readonly SKImageInfo WithColorSpace(SKColorSpace newColorSpace) { SKImageInfo result = this; result.ColorSpace = newColorSpace; return result; } public readonly SKImageInfo WithAlphaType(SKAlphaType newAlphaType) { SKImageInfo result = this; result.AlphaType = newAlphaType; return result; } public readonly bool Equals(SKImageInfo obj) { if (ColorSpace == obj.ColorSpace && Width == obj.Width && Height == obj.Height && ColorType == obj.ColorType) { return AlphaType == obj.AlphaType; } return false; } public override readonly bool Equals(object obj) { if (obj is SKImageInfo obj2) { return Equals(obj2); } return false; } public static bool operator ==(SKImageInfo left, SKImageInfo right) { return left.Equals(right); } public static bool operator !=(SKImageInfo left, SKImageInfo right) { return !left.Equals(right); } public override readonly int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(ColorSpace); hashCode.Add(Width); hashCode.Add(Height); hashCode.Add(ColorType); hashCode.Add(AlphaType); return hashCode.ToHashCode(); } } public class SKManagedStream : SKAbstractManagedStream { private Stream stream; private bool isAsEnd; private bool disposeStream; private bool wasCopied; private WeakReference parent; private WeakReference child; public SKManagedStream(Stream managedStream) : this(managedStream, disposeManagedStream: false) { } public SKManagedStream(Stream managedStream, bool disposeManagedStream) : base(owns: true) { stream = managedStream ?? throw new ArgumentNullException("managedStream"); disposeStream = disposeManagedStream; } public int CopyTo(SKWStream destination) { if (destination == null) { throw new ArgumentNullException("destination"); } int num = 0; Utils.RentedArray rentedArray = Utils.RentArray(81920); try { int num2; while ((num2 = stream.Read((byte[])rentedArray, 0, rentedArray.Length)) > 0) { destination.Write((byte[])rentedArray, num2); num += num2; } destination.Flush(); return num; } finally { rentedArray.Dispose(); } } public SKStreamAsset ToMemoryStream() { using SKDynamicMemoryWStream sKDynamicMemoryWStream = new SKDynamicMemoryWStream(); CopyTo(sKDynamicMemoryWStream); return sKDynamicMemoryWStream.DetachAsStream(); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeManaged() { SKManagedStream sKManagedStream = child?.Target as SKManagedStream; SKManagedStream sKManagedStream2 = parent?.Target as SKManagedStream; if (sKManagedStream != null && sKManagedStream2 != null) { sKManagedStream.parent = parent; sKManagedStream2.child = child; } else if (sKManagedStream != null) { sKManagedStream.parent = null; } else if (sKManagedStream2 != null) { sKManagedStream2.child = null; sKManagedStream2.wasCopied = false; sKManagedStream2.disposeStream = disposeStream; disposeStream = false; } parent = null; child = null; if (disposeStream && stream != null) { stream.Dispose(); stream = null; } base.DisposeManaged(); } private IntPtr OnReadManagedStream(IntPtr buffer, IntPtr size) { if ((int)size < 0) { throw new ArgumentOutOfRangeException("size"); } if (size == IntPtr.Zero) { return IntPtr.Zero; } Utils.RentedArray rentedArray = Utils.RentArray((int)size); try { int num = stream.Read(rentedArray.Array, 0, rentedArray.Length); if (buffer != IntPtr.Zero) { Span span = rentedArray.Span.Slice(0, num); Span destination = buffer.AsSpan(rentedArray.Length); span.CopyTo(destination); } if (!stream.CanSeek && (int)size > 0 && num <= (int)size) { isAsEnd = true; } return (IntPtr)num; } finally { rentedArray.Dispose(); } } protected override IntPtr OnRead(IntPtr buffer, IntPtr size) { VerifyOriginal(); return OnReadManagedStream(buffer, size); } protected override IntPtr OnPeek(IntPtr buffer, IntPtr size) { VerifyOriginal(); if (!stream.CanSeek) { return (IntPtr)0; } long position = stream.Position; IntPtr result = OnReadManagedStream(buffer, size); stream.Position = position; return result; } protected override bool OnIsAtEnd() { VerifyOriginal(); if (!stream.CanSeek) { return isAsEnd; } return stream.Position >= stream.Length; } protected override bool OnHasPosition() { VerifyOriginal(); return stream.CanSeek; } protected override bool OnHasLength() { VerifyOriginal(); return stream.CanSeek; } protected override bool OnRewind() { VerifyOriginal(); if (!stream.CanSeek) { return false; } stream.Position = 0L; return true; } protected override IntPtr OnGetPosition() { VerifyOriginal(); if (!stream.CanSeek) { return (IntPtr)0; } return (IntPtr)stream.Position; } protected override IntPtr OnGetLength() { VerifyOriginal(); if (!stream.CanSeek) { return (IntPtr)0; } return (IntPtr)stream.Length; } protected override bool OnSeek(IntPtr position) { VerifyOriginal(); if (!stream.CanSeek) { return false; } stream.Position = (long)position; return true; } protected override bool OnMove(int offset) { VerifyOriginal(); if (!stream.CanSeek) { return false; } stream.Position += offset; return true; } protected override IntPtr OnCreateNew() { VerifyOriginal(); return IntPtr.Zero; } protected override IntPtr OnDuplicate() { VerifyOriginal(); if (!stream.CanSeek) { return IntPtr.Zero; } SKManagedStream sKManagedStream = new SKManagedStream(stream, disposeStream); sKManagedStream.parent = new WeakReference(this); wasCopied = true; disposeStream = false; child = new WeakReference(sKManagedStream); stream.Position = 0L; return sKManagedStream.Handle; } protected override IntPtr OnFork() { VerifyOriginal(); SKManagedStream sKManagedStream = new SKManagedStream(stream, disposeStream); wasCopied = true; disposeStream = false; return sKManagedStream.Handle; } private void VerifyOriginal() { if (wasCopied) { throw new InvalidOperationException("This stream was duplicated or forked and cannot be read anymore."); } } } public class SKManagedWStream : SKAbstractManagedWStream { private Stream stream; private readonly bool disposeStream; public SKManagedWStream(Stream managedStream) : this(managedStream, disposeManagedStream: false) { } public SKManagedWStream(Stream managedStream, bool disposeManagedStream) : this(managedStream, disposeManagedStream, owns: true) { } private SKManagedWStream(Stream managedStream, bool disposeManagedStream, bool owns) : base(owns) { stream = managedStream; disposeStream = disposeManagedStream; } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeManaged() { if (disposeStream && stream != null) { stream.Dispose(); stream = null; } base.DisposeManaged(); } protected override bool OnWrite(IntPtr buffer, IntPtr size) { int num = (int)size; Utils.RentedArray rentedArray = Utils.RentArray(num); try { if (buffer != IntPtr.Zero) { Marshal.Copy(buffer, (byte[])rentedArray, 0, num); } stream.Write((byte[])rentedArray, 0, num); return true; } finally { rentedArray.Dispose(); } } protected override void OnFlush() { stream.Flush(); } protected override IntPtr OnBytesWritten() { return (IntPtr)stream.Position; } } public class SKAutoMaskFreeImage : IDisposable { private IntPtr image; public SKAutoMaskFreeImage(IntPtr maskImage) { image = maskImage; } public void Dispose() { if (image != IntPtr.Zero) { SKMask.FreeImage(image); image = IntPtr.Zero; } } } [EditorBrowsable(EditorBrowsableState.Never)] [Flags] [Obsolete] public enum SKBlurMaskFilterFlags { None = 0, IgnoreTransform = 1, HighQuality = 2, All = 3 } public class SKMaskFilter : SKObject, ISKReferenceCounted { private const float BlurSigmaScale = 0.57735f; public const int TableMaxLength = 256; internal SKMaskFilter(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public static float ConvertRadiusToSigma(float radius) { if (!(radius > 0f)) { return 0f; } return 0.57735f * radius + 0.5f; } public static float ConvertSigmaToRadius(float sigma) { if (!(sigma > 0.5f)) { return 0f; } return (sigma - 0.5f) / 0.57735f; } public static SKMaskFilter CreateBlur(SKBlurStyle blurStyle, float sigma) { return GetObject(SkiaApi.sk_maskfilter_new_blur(blurStyle, sigma)); } public static SKMaskFilter CreateBlur(SKBlurStyle blurStyle, float sigma, bool respectCTM) { return GetObject(SkiaApi.sk_maskfilter_new_blur_with_flags(blurStyle, sigma, respectCTM)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateBlur(SKBlurStyle, float) instead.")] public static SKMaskFilter CreateBlur(SKBlurStyle blurStyle, float sigma, SKBlurMaskFilterFlags flags) { return CreateBlur(blurStyle, sigma, respectCTM: true); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateBlur(SKBlurStyle, float) instead.")] public static SKMaskFilter CreateBlur(SKBlurStyle blurStyle, float sigma, SKRect occluder) { return CreateBlur(blurStyle, sigma, respectCTM: true); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateBlur(SKBlurStyle, float) instead.")] public static SKMaskFilter CreateBlur(SKBlurStyle blurStyle, float sigma, SKRect occluder, SKBlurMaskFilterFlags flags) { return CreateBlur(blurStyle, sigma, respectCTM: true); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CreateBlur(SKBlurStyle, float, bool) instead.")] public static SKMaskFilter CreateBlur(SKBlurStyle blurStyle, float sigma, SKRect occluder, bool respectCTM) { return CreateBlur(blurStyle, sigma, respectCTM); } public unsafe static SKMaskFilter CreateTable(byte[] table) { if (table == null) { throw new ArgumentNullException("table"); } if (table.Length != 256) { throw new ArgumentException("Table must have a length of {SKColorTable.MaxLength}.", "table"); } fixed (byte* table2 = table) { return GetObject(SkiaApi.sk_maskfilter_new_table(table2)); } } public static SKMaskFilter CreateGamma(float gamma) { return GetObject(SkiaApi.sk_maskfilter_new_gamma(gamma)); } public static SKMaskFilter CreateClip(byte min, byte max) { return GetObject(SkiaApi.sk_maskfilter_new_clip(min, max)); } internal static SKMaskFilter GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKMaskFilter(h, o)); } } public class SKMatrix44 : SKObject { public unsafe SKMatrix Matrix { get { SKMatrix result = default(SKMatrix); SkiaApi.sk_matrix44_to_matrix(Handle, &result); return result; } } public SKMatrix44TypeMask Type => SkiaApi.sk_matrix44_get_type(Handle); public float this[int row, int column] { get { return SkiaApi.sk_matrix44_get(Handle, row, column); } set { SkiaApi.sk_matrix44_set(Handle, row, column, value); } } public bool IsInvertible => SkiaApi.sk_matrix44_invert(Handle, IntPtr.Zero); internal SKMatrix44(IntPtr x, bool owns) : base(x, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_matrix44_destroy(Handle); } public SKMatrix44() : this(SkiaApi.sk_matrix44_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKMatrix44 instance."); } } public SKMatrix44(SKMatrix44 src) : this(IntPtr.Zero, owns: true) { if (src == null) { throw new ArgumentNullException("src"); } Handle = SkiaApi.sk_matrix44_new_copy(src.Handle); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKMatrix44 instance."); } } public SKMatrix44(SKMatrix44 a, SKMatrix44 b) : this(IntPtr.Zero, owns: true) { if (a == null) { throw new ArgumentNullException("a"); } if (b == null) { throw new ArgumentNullException("b"); } Handle = SkiaApi.sk_matrix44_new_concat(a.Handle, b.Handle); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKMatrix44 instance."); } } public unsafe SKMatrix44(SKMatrix src) : this(SkiaApi.sk_matrix44_new_matrix(&src), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKMatrix44 instance."); } } public static SKMatrix44 CreateIdentity() { SKMatrix44 sKMatrix = new SKMatrix44(); sKMatrix.SetIdentity(); return sKMatrix; } [EditorBrowsable(EditorBrowsableState.Never)] public static SKMatrix44 CreateTranslate(float x, float y, float z) { return CreateTranslation(x, y, z); } public static SKMatrix44 CreateTranslation(float x, float y, float z) { SKMatrix44 sKMatrix = new SKMatrix44(); sKMatrix.SetTranslate(x, y, z); return sKMatrix; } public static SKMatrix44 CreateScale(float x, float y, float z) { SKMatrix44 sKMatrix = new SKMatrix44(); sKMatrix.SetScale(x, y, z); return sKMatrix; } public static SKMatrix44 CreateRotation(float x, float y, float z, float radians) { SKMatrix44 sKMatrix = new SKMatrix44(); sKMatrix.SetRotationAbout(x, y, z, radians); return sKMatrix; } public static SKMatrix44 CreateRotationDegrees(float x, float y, float z, float degrees) { SKMatrix44 sKMatrix = new SKMatrix44(); sKMatrix.SetRotationAboutDegrees(x, y, z, degrees); return sKMatrix; } public static SKMatrix44 FromRowMajor(float[] src) { SKMatrix44 sKMatrix = new SKMatrix44(); sKMatrix.SetRowMajor(src); return sKMatrix; } public static SKMatrix44 FromColumnMajor(float[] src) { SKMatrix44 sKMatrix = new SKMatrix44(); sKMatrix.SetColumnMajor(src); return sKMatrix; } public float[] ToColumnMajor() { float[] array = new float[16]; ToColumnMajor(array); return array; } public unsafe void ToColumnMajor(float[] dst) { if (dst == null) { throw new ArgumentNullException("dst"); } if (dst.Length != 16) { throw new ArgumentException("The destination array must be 16 entries.", "dst"); } fixed (float* dst2 = dst) { SkiaApi.sk_matrix44_as_col_major(Handle, dst2); } } public float[] ToRowMajor() { float[] array = new float[16]; ToRowMajor(array); return array; } public unsafe void ToRowMajor(float[] dst) { if (dst == null) { throw new ArgumentNullException("dst"); } if (dst.Length != 16) { throw new ArgumentException("The destination array must be 16 entries.", "dst"); } fixed (float* dst2 = dst) { SkiaApi.sk_matrix44_as_row_major(Handle, dst2); } } public static bool Equal(SKMatrix44 left, SKMatrix44 right) { if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } return SkiaApi.sk_matrix44_equals(left.Handle, right.Handle); } public void SetIdentity() { SkiaApi.sk_matrix44_set_identity(Handle); } public unsafe void SetColumnMajor(float[] src) { if (src == null) { throw new ArgumentNullException("src"); } if (src.Length != 16) { throw new ArgumentException("The source array must be 16 entries.", "src"); } fixed (float* dst = src) { SkiaApi.sk_matrix44_set_col_major(Handle, dst); } } public unsafe void SetRowMajor(float[] src) { if (src == null) { throw new ArgumentNullException("src"); } if (src.Length != 16) { throw new ArgumentException("The source array must be 16 entries.", "src"); } fixed (float* dst = src) { SkiaApi.sk_matrix44_set_row_major(Handle, dst); } } public unsafe void Set3x3ColumnMajor(float[] src) { if (src.Length != 9) { throw new ArgumentException("The source array must be 9 entries.", "src"); } float* dst = stackalloc float[9] { src[0], src[3], src[6], src[1], src[4], src[7], src[2], src[5], src[8] }; SkiaApi.sk_matrix44_set_3x3_row_major(Handle, dst); } public unsafe void Set3x3RowMajor(float[] src) { if (src.Length != 9) { throw new ArgumentException("The source array must be 9 entries.", "src"); } fixed (float* dst = src) { SkiaApi.sk_matrix44_set_3x3_row_major(Handle, dst); } } public void SetTranslate(float dx, float dy, float dz) { SkiaApi.sk_matrix44_set_translate(Handle, dx, dy, dz); } public void SetScale(float sx, float sy, float sz) { SkiaApi.sk_matrix44_set_scale(Handle, sx, sy, sz); } public void SetRotationAboutDegrees(float x, float y, float z, float degrees) { SkiaApi.sk_matrix44_set_rotate_about_degrees(Handle, x, y, z, degrees); } public void SetRotationAbout(float x, float y, float z, float radians) { SkiaApi.sk_matrix44_set_rotate_about_radians(Handle, x, y, z, radians); } public void SetRotationAboutUnit(float x, float y, float z, float radians) { SkiaApi.sk_matrix44_set_rotate_about_radians_unit(Handle, x, y, z, radians); } public void SetConcat(SKMatrix44 a, SKMatrix44 b) { if (a == null) { throw new ArgumentNullException("a"); } if (b == null) { throw new ArgumentNullException("b"); } SkiaApi.sk_matrix44_set_concat(Handle, a.Handle, b.Handle); } public void PreTranslate(float dx, float dy, float dz) { SkiaApi.sk_matrix44_pre_translate(Handle, dx, dy, dz); } public void PostTranslate(float dx, float dy, float dz) { SkiaApi.sk_matrix44_post_translate(Handle, dx, dy, dz); } public void PreScale(float sx, float sy, float sz) { SkiaApi.sk_matrix44_pre_scale(Handle, sx, sy, sz); } public void PostScale(float sx, float sy, float sz) { SkiaApi.sk_matrix44_post_scale(Handle, sx, sy, sz); } public void PreConcat(SKMatrix44 m) { if (m == null) { throw new ArgumentNullException("m"); } SkiaApi.sk_matrix44_pre_concat(Handle, m.Handle); } public void PostConcat(SKMatrix44 m) { if (m == null) { throw new ArgumentNullException("m"); } SkiaApi.sk_matrix44_post_concat(Handle, m.Handle); } public SKMatrix44 Invert() { SKMatrix44 sKMatrix = new SKMatrix44(); if (!Invert(sKMatrix)) { sKMatrix.Dispose(); sKMatrix = null; } return sKMatrix; } public bool Invert(SKMatrix44 inverse) { if (inverse == null) { throw new ArgumentNullException("inverse"); } return SkiaApi.sk_matrix44_invert(Handle, inverse.Handle); } public void Transpose() { SkiaApi.sk_matrix44_transpose(Handle); } public float[] MapScalars(float x, float y, float z, float w) { float[] srcVector = new float[4] { x, y, z, w }; float[] array = new float[4]; MapScalars(srcVector, array); return array; } public float[] MapScalars(float[] srcVector4) { float[] array = new float[4]; MapScalars(srcVector4, array); return array; } public unsafe void MapScalars(float[] srcVector4, float[] dstVector4) { if (srcVector4 == null) { throw new ArgumentNullException("srcVector4"); } if (srcVector4.Length != 4) { throw new ArgumentException("The source vector array must be 4 entries.", "srcVector4"); } if (dstVector4 == null) { throw new ArgumentNullException("dstVector4"); } if (dstVector4.Length != 4) { throw new ArgumentException("The destination vector array must be 4 entries.", "dstVector4"); } fixed (float* src = srcVector4) { fixed (float* dst = dstVector4) { SkiaApi.sk_matrix44_map_scalars(Handle, src, dst); } } } public SKPoint MapPoint(SKPoint src) { return MapPoints(new SKPoint[1] { src })[0]; } public SKPoint[] MapPoints(SKPoint[] src) { if (src == null) { throw new ArgumentNullException("src"); } int num = src.Length; int num2 = num * 2; float[] array = new float[num2]; int num3 = 0; int num4 = 0; while (num3 < num) { array[num4] = src[num3].X; array[num4 + 1] = src[num3].Y; num3++; num4 += 2; } float[] array2 = MapVector2(array); SKPoint[] array3 = new SKPoint[num]; int num5 = 0; int num6 = 0; while (num5 < num) { array3[num5].X = array2[num6]; array3[num5].Y = array2[num6 + 1]; num5++; num6 += 4; } return array3; } public float[] MapVector2(float[] src2) { if (src2 == null) { throw new ArgumentNullException("src2"); } if (src2.Length % 2 != 0) { throw new ArgumentException("The source vector array must be a set of pairs.", "src2"); } float[] array = new float[src2.Length * 2]; MapVector2(src2, array); return array; } public unsafe void MapVector2(float[] src2, float[] dst4) { if (src2 == null) { throw new ArgumentNullException("src2"); } if (src2.Length % 2 != 0) { throw new ArgumentException("The source vector array must be a set of pairs.", "src2"); } if (dst4 == null) { throw new ArgumentNullException("dst4"); } if (dst4.Length % 4 != 0) { throw new ArgumentException("The destination vector array must be a set quads.", "dst4"); } if (src2.Length / 2 != dst4.Length / 4) { throw new ArgumentException("The source vector array must have the same number of pairs as the destination vector array has quads.", "dst4"); } fixed (float* src3 = src2) { fixed (float* dst5 = dst4) { SkiaApi.sk_matrix44_map2(Handle, src3, src2.Length / 2, dst5); } } } public bool Preserves2DAxisAlignment(float epsilon) { return SkiaApi.sk_matrix44_preserves_2d_axis_alignment(Handle, epsilon); } public double Determinant() { return SkiaApi.sk_matrix44_determinant(Handle); } public static implicit operator SKMatrix44(SKMatrix matrix) { return new SKMatrix44(matrix); } internal static SKMatrix44 GetObject(IntPtr handle, bool owns = true) { return SKObject.GetOrAddObject(handle, owns, (IntPtr h, bool o) => new SKMatrix44(h, o)); } } public class SKNoDrawCanvas : SKCanvas { internal SKNoDrawCanvas(IntPtr handle, bool owns) : base(handle, owns) { } public SKNoDrawCanvas(int width, int height) : this(IntPtr.Zero, owns: true) { Handle = SkiaApi.sk_nodraw_canvas_new(width, height); } } public class SKNWayCanvas : SKNoDrawCanvas { internal SKNWayCanvas(IntPtr handle, bool owns) : base(handle, owns) { } public SKNWayCanvas(int width, int height) : this(IntPtr.Zero, owns: true) { Handle = SkiaApi.sk_nway_canvas_new(width, height); } public void AddCanvas(SKCanvas canvas) { if (canvas == null) { throw new ArgumentNullException("canvas"); } SkiaApi.sk_nway_canvas_add_canvas(Handle, canvas.Handle); } public void RemoveCanvas(SKCanvas canvas) { if (canvas == null) { throw new ArgumentNullException("canvas"); } SkiaApi.sk_nway_canvas_remove_canvas(Handle, canvas.Handle); } public void RemoveAll() { SkiaApi.sk_nway_canvas_remove_all(Handle); } } public abstract class SKObject : SKNativeObject { private readonly object locker = new object(); private ConcurrentDictionary ownedObjects; private ConcurrentDictionary keepAliveObjects; internal ConcurrentDictionary OwnedObjects { get { if (ownedObjects == null) { lock (locker) { if (ownedObjects == null) { ownedObjects = new ConcurrentDictionary(); } } } return ownedObjects; } } internal ConcurrentDictionary KeepAliveObjects { get { if (keepAliveObjects == null) { lock (locker) { if (keepAliveObjects == null) { keepAliveObjects = new ConcurrentDictionary(); } } } return keepAliveObjects; } } public override IntPtr Handle { get { return base.Handle; } protected set { if (value == IntPtr.Zero) { DeregisterHandle(Handle, this); base.Handle = value; } else { base.Handle = value; RegisterHandle(Handle, this); } } } static SKObject() { SkiaSharpVersion.CheckNativeLibraryCompatible(throwIfIncompatible: true); SKColorSpace.EnsureStaticInstanceAreInitialized(); SKData.EnsureStaticInstanceAreInitialized(); SKFontManager.EnsureStaticInstanceAreInitialized(); SKTypeface.EnsureStaticInstanceAreInitialized(); } internal SKObject(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeUnownedManaged() { if (ownedObjects == null) { return; } foreach (KeyValuePair ownedObject in ownedObjects) { SKObject value = ownedObject.Value; if (value != null && !value.OwnsHandle) { value.DisposeInternal(); } } } protected override void DisposeManaged() { if (ownedObjects != null) { foreach (KeyValuePair ownedObject in ownedObjects) { SKObject value = ownedObject.Value; if (value != null && value.OwnsHandle) { value.DisposeInternal(); } } ownedObjects.Clear(); } keepAliveObjects?.Clear(); } protected override void DisposeNative() { if (this is ISKReferenceCounted obj) { obj.SafeUnRef(); } } internal static TSkiaObject GetOrAddObject(IntPtr handle, Func objectFactory) where TSkiaObject : SKObject { if (handle == IntPtr.Zero) { return null; } return HandleDictionary.GetOrAddObject(handle, owns: true, unrefExisting: true, objectFactory); } internal static TSkiaObject GetOrAddObject(IntPtr handle, bool owns, Func objectFactory) where TSkiaObject : SKObject { if (handle == IntPtr.Zero) { return null; } return HandleDictionary.GetOrAddObject(handle, owns, unrefExisting: true, objectFactory); } internal static TSkiaObject GetOrAddObject(IntPtr handle, bool owns, bool unrefExisting, Func objectFactory) where TSkiaObject : SKObject { if (handle == IntPtr.Zero) { return null; } return HandleDictionary.GetOrAddObject(handle, owns, unrefExisting, objectFactory); } internal static void RegisterHandle(IntPtr handle, SKObject instance) { if (!(handle == IntPtr.Zero) && instance != null) { HandleDictionary.RegisterHandle(handle, instance); } } internal static void DeregisterHandle(IntPtr handle, SKObject instance) { if (!(handle == IntPtr.Zero)) { HandleDictionary.DeregisterHandle(handle, instance); } } internal static bool GetInstance(IntPtr handle, out TSkiaObject instance) where TSkiaObject : SKObject { if (handle == IntPtr.Zero) { instance = null; return false; } return HandleDictionary.GetInstance(handle, out instance); } internal void PreventPublicDisposal() { base.IgnorePublicDispose = true; } internal void RevokeOwnership(SKObject newOwner) { OwnsHandle = false; base.IgnorePublicDispose = true; if (newOwner == null) { DisposeInternal(); } else { newOwner.OwnedObjects[Handle] = this; } } internal static T OwnedBy(T child, SKObject owner) where T : SKObject { if (child != null) { owner.OwnedObjects[child.Handle] = child; } return child; } internal static T Owned(T owner, SKObject child) where T : SKObject { if (child != null) { if (owner != null) { owner.OwnedObjects[child.Handle] = child; } else { child.Dispose(); } } return owner; } internal static T Referenced(T owner, SKObject child) where T : SKObject { if (child != null && owner != null) { owner.KeepAliveObjects[child.Handle] = child; } return owner; } internal static T[] PtrToStructureArray(IntPtr intPtr, int count) { T[] array = new T[count]; int num = Marshal.SizeOf(); for (int i = 0; i < count; i++) { IntPtr ptr = new IntPtr(intPtr.ToInt64() + i * num); array[i] = Marshal.PtrToStructure(ptr); } return array; } internal static T PtrToStructure(IntPtr intPtr, int index) { int num = Marshal.SizeOf(); IntPtr ptr = new IntPtr(intPtr.ToInt64() + index * num); return Marshal.PtrToStructure(ptr); } } public abstract class SKNativeObject : IDisposable { internal bool fromFinalizer; private int isDisposed; public virtual IntPtr Handle { get; protected set; } protected internal virtual bool OwnsHandle { get; protected set; } protected internal bool IgnorePublicDispose { get; set; } protected internal bool IsDisposed => isDisposed == 1; internal SKNativeObject(IntPtr handle) : this(handle, ownsHandle: true) { } internal SKNativeObject(IntPtr handle, bool ownsHandle) { Handle = handle; OwnsHandle = ownsHandle; } ~SKNativeObject() { fromFinalizer = true; Dispose(disposing: false); } protected virtual void DisposeUnownedManaged() { } protected virtual void DisposeManaged() { } protected virtual void DisposeNative() { } protected virtual void Dispose(bool disposing) { if (Interlocked.CompareExchange(ref isDisposed, 1, 0) == 0) { if (disposing) { DisposeUnownedManaged(); } if (Handle != IntPtr.Zero && OwnsHandle) { DisposeNative(); } if (disposing) { DisposeManaged(); } Handle = IntPtr.Zero; } } public void Dispose() { if (!IgnorePublicDispose) { DisposeInternal(); } } protected internal void DisposeInternal() { Dispose(disposing: true); GC.SuppressFinalize(this); } } internal static class SKObjectExtensions { public static bool IsUnique(this IntPtr handle, bool isVirtual) { if (isVirtual) { return SkiaApi.sk_refcnt_unique(handle); } return SkiaApi.sk_nvrefcnt_unique(handle); } public static int GetReferenceCount(this IntPtr handle, bool isVirtual) { if (isVirtual) { return SkiaApi.sk_refcnt_get_ref_count(handle); } return SkiaApi.sk_nvrefcnt_get_ref_count(handle); } public static void SafeRef(this ISKReferenceCounted obj) { if (obj is ISKNonVirtualReferenceCounted iSKNonVirtualReferenceCounted) { iSKNonVirtualReferenceCounted.ReferenceNative(); } else { SkiaApi.sk_refcnt_safe_unref(obj.Handle); } } public static void SafeUnRef(this ISKReferenceCounted obj) { if (obj is ISKNonVirtualReferenceCounted iSKNonVirtualReferenceCounted) { iSKNonVirtualReferenceCounted.UnreferenceNative(); } else { SkiaApi.sk_refcnt_safe_unref(obj.Handle); } } public static int GetReferenceCount(this ISKReferenceCounted obj) { if (obj is ISKNonVirtualReferenceCounted) { return SkiaApi.sk_nvrefcnt_get_ref_count(obj.Handle); } return SkiaApi.sk_refcnt_get_ref_count(obj.Handle); } } internal interface ISKReferenceCounted { IntPtr Handle { get; } } internal interface ISKNonVirtualReferenceCounted : ISKReferenceCounted { void ReferenceNative(); void UnreferenceNative(); } internal interface ISKSkipObjectRegistration { } public class SKOverdrawCanvas : SKNWayCanvas { internal SKOverdrawCanvas(IntPtr handle, bool owns) : base(handle, owns) { } public SKOverdrawCanvas(SKCanvas canvas) : this(IntPtr.Zero, owns: true) { if (canvas == null) { throw new ArgumentNullException("canvas"); } Handle = SkiaApi.sk_overdraw_canvas_new(canvas.Handle); } } public enum SKPaintHinting { NoHinting, Slight, Normal, Full } public class SKPaint : SKObject, ISKSkipObjectRegistration { private SKFont font; private bool lcdRenderText; public bool IsAntialias { get { return SkiaApi.sk_paint_is_antialias(Handle); } set { SkiaApi.sk_paint_set_antialias(Handle, value); UpdateFontEdging(value); } } public bool IsDither { get { return SkiaApi.sk_paint_is_dither(Handle); } set { SkiaApi.sk_paint_set_dither(Handle, value); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public bool IsVerticalText { get { return false; } set { } } public bool IsLinearText { get { return GetFont().LinearMetrics; } set { GetFont().LinearMetrics = value; } } public bool SubpixelText { get { return GetFont().Subpixel; } set { GetFont().Subpixel = value; } } public bool LcdRenderText { get { return lcdRenderText; } set { lcdRenderText = value; UpdateFontEdging(IsAntialias); } } public bool IsEmbeddedBitmapText { get { return GetFont().EmbeddedBitmaps; } set { GetFont().EmbeddedBitmaps = value; } } public bool IsAutohinted { get { return GetFont().ForceAutoHinting; } set { GetFont().ForceAutoHinting = value; } } public SKPaintHinting HintingLevel { get { return (SKPaintHinting)GetFont().Hinting; } set { GetFont().Hinting = (SKFontHinting)value; } } public bool FakeBoldText { get { return GetFont().Embolden; } set { GetFont().Embolden = value; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public bool DeviceKerningEnabled { get { return false; } set { } } public bool IsStroke { get { return Style != SKPaintStyle.Fill; } set { Style = (value ? SKPaintStyle.Stroke : SKPaintStyle.Fill); } } public SKPaintStyle Style { get { return SkiaApi.sk_paint_get_style(Handle); } set { SkiaApi.sk_paint_set_style(Handle, value); } } public SKColor Color { get { return SkiaApi.sk_paint_get_color(Handle); } set { SkiaApi.sk_paint_set_color(Handle, (uint)value); } } public unsafe SKColorF ColorF { get { SKColorF result = default(SKColorF); SkiaApi.sk_paint_get_color4f(Handle, &result); return result; } set { SkiaApi.sk_paint_set_color4f(Handle, &value, IntPtr.Zero); } } public float StrokeWidth { get { return SkiaApi.sk_paint_get_stroke_width(Handle); } set { SkiaApi.sk_paint_set_stroke_width(Handle, value); } } public float StrokeMiter { get { return SkiaApi.sk_paint_get_stroke_miter(Handle); } set { SkiaApi.sk_paint_set_stroke_miter(Handle, value); } } public SKStrokeCap StrokeCap { get { return SkiaApi.sk_paint_get_stroke_cap(Handle); } set { SkiaApi.sk_paint_set_stroke_cap(Handle, value); } } public SKStrokeJoin StrokeJoin { get { return SkiaApi.sk_paint_get_stroke_join(Handle); } set { SkiaApi.sk_paint_set_stroke_join(Handle, value); } } public SKShader Shader { get { return SKShader.GetObject(SkiaApi.sk_paint_get_shader(Handle)); } set { SkiaApi.sk_paint_set_shader(Handle, value?.Handle ?? IntPtr.Zero); } } public SKMaskFilter MaskFilter { get { return SKMaskFilter.GetObject(SkiaApi.sk_paint_get_maskfilter(Handle)); } set { SkiaApi.sk_paint_set_maskfilter(Handle, value?.Handle ?? IntPtr.Zero); } } public SKColorFilter ColorFilter { get { return SKColorFilter.GetObject(SkiaApi.sk_paint_get_colorfilter(Handle)); } set { SkiaApi.sk_paint_set_colorfilter(Handle, value?.Handle ?? IntPtr.Zero); } } public SKImageFilter ImageFilter { get { return SKImageFilter.GetObject(SkiaApi.sk_paint_get_imagefilter(Handle)); } set { SkiaApi.sk_paint_set_imagefilter(Handle, value?.Handle ?? IntPtr.Zero); } } public SKBlendMode BlendMode { get { return SkiaApi.sk_paint_get_blendmode(Handle); } set { SkiaApi.sk_paint_set_blendmode(Handle, value); } } public SKFilterQuality FilterQuality { get { return SkiaApi.sk_paint_get_filter_quality(Handle); } set { SkiaApi.sk_paint_set_filter_quality(Handle, value); } } public SKTypeface Typeface { get { return GetFont().Typeface; } set { GetFont().Typeface = value; } } public float TextSize { get { return GetFont().Size; } set { GetFont().Size = value; } } public SKTextAlign TextAlign { get { return SkiaApi.sk_compatpaint_get_text_align(Handle); } set { SkiaApi.sk_compatpaint_set_text_align(Handle, value); } } public SKTextEncoding TextEncoding { get { return SkiaApi.sk_compatpaint_get_text_encoding(Handle); } set { SkiaApi.sk_compatpaint_set_text_encoding(Handle, value); } } public float TextScaleX { get { return GetFont().ScaleX; } set { GetFont().ScaleX = value; } } public float TextSkewX { get { return GetFont().SkewX; } set { GetFont().SkewX = value; } } public SKPathEffect PathEffect { get { return SKPathEffect.GetObject(SkiaApi.sk_paint_get_path_effect(Handle)); } set { SkiaApi.sk_paint_set_path_effect(Handle, value?.Handle ?? IntPtr.Zero); } } public float FontSpacing => GetFont().Spacing; public SKFontMetrics FontMetrics => GetFont().Metrics; internal SKPaint(IntPtr handle, bool owns) : base(handle, owns) { } public SKPaint() : this(SkiaApi.sk_compatpaint_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPaint instance."); } } public SKPaint(SKFont font) : this(IntPtr.Zero, owns: true) { if (font == null) { throw new ArgumentNullException("font"); } Handle = SkiaApi.sk_compatpaint_new_with_font(font.Handle); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPaint instance."); } LcdRenderText = font.Edging == SKFontEdging.SubpixelAntialias; } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_compatpaint_delete(Handle); } public void Reset() { SkiaApi.sk_compatpaint_reset(Handle); } public unsafe void SetColor(SKColorF color, SKColorSpace colorspace) { SkiaApi.sk_paint_set_color4f(Handle, &color, colorspace?.Handle ?? IntPtr.Zero); } public float GetFontMetrics(out SKFontMetrics metrics) { return GetFont().GetFontMetrics(out metrics); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetFontMetrics (out SKFontMetrics) instead.")] public float GetFontMetrics(out SKFontMetrics metrics, float scale) { return GetFontMetrics(out metrics); } public SKPaint Clone() { return GetObject(SkiaApi.sk_compatpaint_clone(Handle)); } public float MeasureText(string text) { return GetFont().MeasureText(text, this); } public float MeasureText(ReadOnlySpan text) { return GetFont().MeasureText(text, this); } public float MeasureText(byte[] text) { return GetFont().MeasureText(text, TextEncoding, this); } public float MeasureText(ReadOnlySpan text) { return GetFont().MeasureText(text, TextEncoding, this); } public float MeasureText(IntPtr buffer, int length) { return GetFont().MeasureText(buffer, length, TextEncoding, this); } public float MeasureText(IntPtr buffer, IntPtr length) { return GetFont().MeasureText(buffer, (int)length, TextEncoding, this); } public float MeasureText(string text, ref SKRect bounds) { return GetFont().MeasureText(text, out bounds, this); } public float MeasureText(ReadOnlySpan text, ref SKRect bounds) { return GetFont().MeasureText(text, out bounds, this); } public float MeasureText(byte[] text, ref SKRect bounds) { return GetFont().MeasureText(text, TextEncoding, out bounds, this); } public float MeasureText(ReadOnlySpan text, ref SKRect bounds) { return GetFont().MeasureText(text, TextEncoding, out bounds, this); } public float MeasureText(IntPtr buffer, int length, ref SKRect bounds) { return GetFont().MeasureText(buffer, length, TextEncoding, out bounds, this); } public float MeasureText(IntPtr buffer, IntPtr length, ref SKRect bounds) { return GetFont().MeasureText(buffer, (int)length, TextEncoding, out bounds, this); } public long BreakText(string text, float maxWidth) { float measuredWidth; return GetFont().BreakText(text, maxWidth, out measuredWidth, this); } public long BreakText(string text, float maxWidth, out float measuredWidth) { return GetFont().BreakText(text, maxWidth, out measuredWidth, this); } public long BreakText(string text, float maxWidth, out float measuredWidth, out string measuredText) { if (text == null) { throw new ArgumentNullException("text"); } int num = GetFont().BreakText(text, maxWidth, out measuredWidth, this); if (num == 0) { measuredText = string.Empty; return 0L; } if (num == text.Length) { measuredText = text; return text.Length; } measuredText = text.Substring(0, num); return num; } public long BreakText(ReadOnlySpan text, float maxWidth) { float measuredWidth; return GetFont().BreakText(text, maxWidth, out measuredWidth, this); } public long BreakText(ReadOnlySpan text, float maxWidth, out float measuredWidth) { return GetFont().BreakText(text, maxWidth, out measuredWidth, this); } public long BreakText(byte[] text, float maxWidth) { float measuredWidth; return GetFont().BreakText(text, TextEncoding, maxWidth, out measuredWidth, this); } public long BreakText(byte[] text, float maxWidth, out float measuredWidth) { return GetFont().BreakText(text, TextEncoding, maxWidth, out measuredWidth, this); } public long BreakText(ReadOnlySpan text, float maxWidth) { float measuredWidth; return GetFont().BreakText(text, TextEncoding, maxWidth, out measuredWidth, this); } public long BreakText(ReadOnlySpan text, float maxWidth, out float measuredWidth) { return GetFont().BreakText(text, TextEncoding, maxWidth, out measuredWidth, this); } public long BreakText(IntPtr buffer, int length, float maxWidth) { float measuredWidth; return GetFont().BreakText(buffer, length, TextEncoding, maxWidth, out measuredWidth, this); } public long BreakText(IntPtr buffer, int length, float maxWidth, out float measuredWidth) { return GetFont().BreakText(buffer, length, TextEncoding, maxWidth, out measuredWidth, this); } public long BreakText(IntPtr buffer, IntPtr length, float maxWidth) { float measuredWidth; return GetFont().BreakText(buffer, (int)length, TextEncoding, maxWidth, out measuredWidth, this); } public long BreakText(IntPtr buffer, IntPtr length, float maxWidth, out float measuredWidth) { return GetFont().BreakText(buffer, (int)length, TextEncoding, maxWidth, out measuredWidth, this); } public SKPath GetTextPath(string text, float x, float y) { return GetFont().GetTextPath(text, new SKPoint(x, y)); } public SKPath GetTextPath(ReadOnlySpan text, float x, float y) { return GetFont().GetTextPath(text, new SKPoint(x, y)); } public SKPath GetTextPath(byte[] text, float x, float y) { return GetFont().GetTextPath(text, TextEncoding, new SKPoint(x, y)); } public SKPath GetTextPath(ReadOnlySpan text, float x, float y) { return GetFont().GetTextPath(text, TextEncoding, new SKPoint(x, y)); } public SKPath GetTextPath(IntPtr buffer, int length, float x, float y) { return GetFont().GetTextPath(buffer, length, TextEncoding, new SKPoint(x, y)); } public SKPath GetTextPath(IntPtr buffer, IntPtr length, float x, float y) { return GetFont().GetTextPath(buffer, (int)length, TextEncoding, new SKPoint(x, y)); } public SKPath GetTextPath(string text, SKPoint[] points) { return GetFont().GetTextPath(text, points); } public SKPath GetTextPath(ReadOnlySpan text, ReadOnlySpan points) { return GetFont().GetTextPath(text, points); } public SKPath GetTextPath(byte[] text, SKPoint[] points) { return GetFont().GetTextPath(text, TextEncoding, points); } public SKPath GetTextPath(ReadOnlySpan text, ReadOnlySpan points) { return GetFont().GetTextPath(text, TextEncoding, points); } public SKPath GetTextPath(IntPtr buffer, int length, SKPoint[] points) { return GetFont().GetTextPath(buffer, length, TextEncoding, points); } public SKPath GetTextPath(IntPtr buffer, int length, ReadOnlySpan points) { return GetFont().GetTextPath(buffer, length, TextEncoding, points); } public SKPath GetTextPath(IntPtr buffer, IntPtr length, SKPoint[] points) { return GetFont().GetTextPath(buffer, (int)length, TextEncoding, points); } public SKPath GetFillPath(SKPath src) { return GetFillPath(src, 1f); } public SKPath GetFillPath(SKPath src, float resScale) { SKPath sKPath = new SKPath(); if (GetFillPath(src, sKPath, resScale)) { return sKPath; } sKPath.Dispose(); return null; } public SKPath GetFillPath(SKPath src, SKRect cullRect) { return GetFillPath(src, cullRect, 1f); } public SKPath GetFillPath(SKPath src, SKRect cullRect, float resScale) { SKPath sKPath = new SKPath(); if (GetFillPath(src, sKPath, cullRect, resScale)) { return sKPath; } sKPath.Dispose(); return null; } public bool GetFillPath(SKPath src, SKPath dst) { return GetFillPath(src, dst, 1f); } public unsafe bool GetFillPath(SKPath src, SKPath dst, float resScale) { if (src == null) { throw new ArgumentNullException("src"); } if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_paint_get_fill_path(Handle, src.Handle, dst.Handle, null, resScale); } public bool GetFillPath(SKPath src, SKPath dst, SKRect cullRect) { return GetFillPath(src, dst, cullRect, 1f); } public unsafe bool GetFillPath(SKPath src, SKPath dst, SKRect cullRect, float resScale) { if (src == null) { throw new ArgumentNullException("src"); } if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_paint_get_fill_path(Handle, src.Handle, dst.Handle, &cullRect, resScale); } public int CountGlyphs(string text) { return GetFont().CountGlyphs(text); } public int CountGlyphs(ReadOnlySpan text) { return GetFont().CountGlyphs(text); } public int CountGlyphs(byte[] text) { return GetFont().CountGlyphs(text, TextEncoding); } public int CountGlyphs(ReadOnlySpan text) { return GetFont().CountGlyphs(text, TextEncoding); } public int CountGlyphs(IntPtr text, int length) { return GetFont().CountGlyphs(text, length, TextEncoding); } public int CountGlyphs(IntPtr text, IntPtr length) { return GetFont().CountGlyphs(text, (int)length, TextEncoding); } public ushort[] GetGlyphs(string text) { return GetFont().GetGlyphs(text); } public ushort[] GetGlyphs(ReadOnlySpan text) { return GetFont().GetGlyphs(text); } public ushort[] GetGlyphs(byte[] text) { return GetFont().GetGlyphs(text, TextEncoding); } public ushort[] GetGlyphs(ReadOnlySpan text) { return GetFont().GetGlyphs(text, TextEncoding); } public ushort[] GetGlyphs(IntPtr text, int length) { return GetFont().GetGlyphs(text, length, TextEncoding); } public ushort[] GetGlyphs(IntPtr text, IntPtr length) { return GetFont().GetGlyphs(text, (int)length, TextEncoding); } public bool ContainsGlyphs(string text) { return GetFont().ContainsGlyphs(text); } public bool ContainsGlyphs(ReadOnlySpan text) { return GetFont().ContainsGlyphs(text); } public bool ContainsGlyphs(byte[] text) { return GetFont().ContainsGlyphs(text, TextEncoding); } public bool ContainsGlyphs(ReadOnlySpan text) { return GetFont().ContainsGlyphs(text, TextEncoding); } public bool ContainsGlyphs(IntPtr text, int length) { return GetFont().ContainsGlyphs(text, length, TextEncoding); } public bool ContainsGlyphs(IntPtr text, IntPtr length) { return GetFont().ContainsGlyphs(text, (int)length, TextEncoding); } public SKPoint[] GetGlyphPositions(string text, SKPoint origin = default(SKPoint)) { return GetFont().GetGlyphPositions(text, origin); } public SKPoint[] GetGlyphPositions(ReadOnlySpan text, SKPoint origin = default(SKPoint)) { return GetFont().GetGlyphPositions(text, origin); } public SKPoint[] GetGlyphPositions(ReadOnlySpan text, SKPoint origin = default(SKPoint)) { return GetFont().GetGlyphPositions(text, TextEncoding, origin); } public SKPoint[] GetGlyphPositions(IntPtr text, int length, SKPoint origin = default(SKPoint)) { return GetFont().GetGlyphPositions(text, length, TextEncoding, origin); } public float[] GetGlyphOffsets(string text, float origin = 0f) { return GetFont().GetGlyphOffsets(text, origin); } public float[] GetGlyphOffsets(ReadOnlySpan text, float origin = 0f) { return GetFont().GetGlyphOffsets(text, origin); } public float[] GetGlyphOffsets(ReadOnlySpan text, float origin = 0f) { return GetFont().GetGlyphOffsets(text, TextEncoding, origin); } public float[] GetGlyphOffsets(IntPtr text, int length, float origin = 0f) { return GetFont().GetGlyphOffsets(text, length, TextEncoding, origin); } public float[] GetGlyphWidths(string text) { return GetFont().GetGlyphWidths(text, this); } public float[] GetGlyphWidths(ReadOnlySpan text) { return GetFont().GetGlyphWidths(text, this); } public float[] GetGlyphWidths(byte[] text) { return GetFont().GetGlyphWidths(text, TextEncoding, this); } public float[] GetGlyphWidths(ReadOnlySpan text) { return GetFont().GetGlyphWidths(text, TextEncoding, this); } public float[] GetGlyphWidths(IntPtr text, int length) { return GetFont().GetGlyphWidths(text, length, TextEncoding, this); } public float[] GetGlyphWidths(IntPtr text, IntPtr length) { return GetFont().GetGlyphWidths(text, (int)length, TextEncoding, this); } public float[] GetGlyphWidths(string text, out SKRect[] bounds) { return GetFont().GetGlyphWidths(text, out bounds, this); } public float[] GetGlyphWidths(ReadOnlySpan text, out SKRect[] bounds) { return GetFont().GetGlyphWidths(text, out bounds, this); } public float[] GetGlyphWidths(byte[] text, out SKRect[] bounds) { return GetFont().GetGlyphWidths(text, TextEncoding, out bounds, this); } public float[] GetGlyphWidths(ReadOnlySpan text, out SKRect[] bounds) { return GetFont().GetGlyphWidths(text, TextEncoding, out bounds, this); } public float[] GetGlyphWidths(IntPtr text, int length, out SKRect[] bounds) { return GetFont().GetGlyphWidths(text, length, TextEncoding, out bounds, this); } public float[] GetGlyphWidths(IntPtr text, IntPtr length, out SKRect[] bounds) { return GetFont().GetGlyphWidths(text, (int)length, TextEncoding, out bounds, this); } public float[] GetTextIntercepts(string text, float x, float y, float upperBounds, float lowerBounds) { return GetTextIntercepts(text.AsSpan(), x, y, upperBounds, lowerBounds); } public float[] GetTextIntercepts(ReadOnlySpan text, float x, float y, float upperBounds, float lowerBounds) { if (text == null) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.Create(text, GetFont(), new SKPoint(x, y)); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetTextIntercepts(byte[] text, float x, float y, float upperBounds, float lowerBounds) { return GetTextIntercepts(text.AsSpan(), x, y, upperBounds, lowerBounds); } public float[] GetTextIntercepts(ReadOnlySpan text, float x, float y, float upperBounds, float lowerBounds) { if (text == null) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.Create(text, TextEncoding, GetFont(), new SKPoint(x, y)); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetTextIntercepts(IntPtr text, IntPtr length, float x, float y, float upperBounds, float lowerBounds) { return GetTextIntercepts(text, (int)length, x, y, upperBounds, lowerBounds); } public float[] GetTextIntercepts(IntPtr text, int length, float x, float y, float upperBounds, float lowerBounds) { if (text == IntPtr.Zero && length != 0) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.Create(text, length, TextEncoding, GetFont(), new SKPoint(x, y)); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetTextIntercepts(SKTextBlob text, float upperBounds, float lowerBounds) { if (text == null) { throw new ArgumentNullException("text"); } return text.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetPositionedTextIntercepts(string text, SKPoint[] positions, float upperBounds, float lowerBounds) { return GetPositionedTextIntercepts(text.AsSpan(), positions, upperBounds, lowerBounds); } public float[] GetPositionedTextIntercepts(ReadOnlySpan text, ReadOnlySpan positions, float upperBounds, float lowerBounds) { if (text == null) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.CreatePositioned(text, GetFont(), positions); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetPositionedTextIntercepts(byte[] text, SKPoint[] positions, float upperBounds, float lowerBounds) { return GetPositionedTextIntercepts(text.AsSpan(), positions, upperBounds, lowerBounds); } public float[] GetPositionedTextIntercepts(ReadOnlySpan text, ReadOnlySpan positions, float upperBounds, float lowerBounds) { if (text == null) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.CreatePositioned(text, TextEncoding, GetFont(), positions); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetPositionedTextIntercepts(IntPtr text, int length, SKPoint[] positions, float upperBounds, float lowerBounds) { return GetPositionedTextIntercepts(text, (IntPtr)length, positions, upperBounds, lowerBounds); } public float[] GetPositionedTextIntercepts(IntPtr text, IntPtr length, SKPoint[] positions, float upperBounds, float lowerBounds) { if (text == IntPtr.Zero && length != IntPtr.Zero) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.CreatePositioned(text, (int)length, TextEncoding, GetFont(), positions); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetHorizontalTextIntercepts(string text, float[] xpositions, float y, float upperBounds, float lowerBounds) { return GetHorizontalTextIntercepts(text.AsSpan(), xpositions, y, upperBounds, lowerBounds); } public float[] GetHorizontalTextIntercepts(ReadOnlySpan text, ReadOnlySpan xpositions, float y, float upperBounds, float lowerBounds) { if (text == null) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.CreateHorizontal(text, GetFont(), xpositions, y); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetHorizontalTextIntercepts(byte[] text, float[] xpositions, float y, float upperBounds, float lowerBounds) { return GetHorizontalTextIntercepts(text.AsSpan(), xpositions, y, upperBounds, lowerBounds); } public float[] GetHorizontalTextIntercepts(ReadOnlySpan text, ReadOnlySpan xpositions, float y, float upperBounds, float lowerBounds) { if (text == null) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.CreateHorizontal(text, TextEncoding, GetFont(), xpositions, y); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public float[] GetHorizontalTextIntercepts(IntPtr text, int length, float[] xpositions, float y, float upperBounds, float lowerBounds) { return GetHorizontalTextIntercepts(text, (IntPtr)length, xpositions, y, upperBounds, lowerBounds); } public float[] GetHorizontalTextIntercepts(IntPtr text, IntPtr length, float[] xpositions, float y, float upperBounds, float lowerBounds) { if (text == IntPtr.Zero && length != IntPtr.Zero) { throw new ArgumentNullException("text"); } using SKTextBlob sKTextBlob = SKTextBlob.CreateHorizontal(text, (int)length, TextEncoding, GetFont(), xpositions, y); return sKTextBlob.GetIntercepts(upperBounds, lowerBounds, this); } public SKFont ToFont() { return SKFont.GetObject(SkiaApi.sk_compatpaint_make_font(Handle)); } internal SKFont GetFont() { return font ?? (font = SKObject.OwnedBy(SKFont.GetObject(SkiaApi.sk_compatpaint_get_font(Handle), owns: false), this)); } private void UpdateFontEdging(bool antialias) { SKFontEdging edging = SKFontEdging.Alias; if (antialias) { edging = ((!lcdRenderText) ? SKFontEdging.Antialias : SKFontEdging.SubpixelAntialias); } GetFont().Edging = edging; } internal static SKPaint GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new SKPaint(handle, owns: true); } return null; } } public enum SKPathConvexity { Unknown, Convex, Concave } public class SKPath : SKObject, ISKSkipObjectRegistration { public class Iterator : SKObject, ISKSkipObjectRegistration { private readonly SKPath path; internal Iterator(SKPath path, bool forceClose) : base(SkiaApi.sk_path_create_iter(path.Handle, forceClose ? 1 : 0), owns: true) { this.path = path; } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_path_iter_destroy(Handle); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Next(SKPoint[]) instead.")] public SKPathVerb Next(SKPoint[] points, bool doConsumeDegenerates, bool exact) { return Next(points); } public SKPathVerb Next(SKPoint[] points) { return Next(new Span(points)); } public unsafe SKPathVerb Next(Span points) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length != 4) { throw new ArgumentException("Must be an array of four elements.", "points"); } fixed (SKPoint* points2 = points) { return SkiaApi.sk_path_iter_next(Handle, points2); } } public float ConicWeight() { return SkiaApi.sk_path_iter_conic_weight(Handle); } public bool IsCloseLine() { return SkiaApi.sk_path_iter_is_close_line(Handle) != 0; } public bool IsCloseContour() { return SkiaApi.sk_path_iter_is_closed_contour(Handle) != 0; } } public class RawIterator : SKObject, ISKSkipObjectRegistration { private readonly SKPath path; internal RawIterator(SKPath path) : base(SkiaApi.sk_path_create_rawiter(path.Handle), owns: true) { this.path = path; } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_path_rawiter_destroy(Handle); } public SKPathVerb Next(SKPoint[] points) { return Next(new Span(points)); } public unsafe SKPathVerb Next(Span points) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length != 4) { throw new ArgumentException("Must be an array of four elements.", "points"); } fixed (SKPoint* points2 = points) { return SkiaApi.sk_path_rawiter_next(Handle, points2); } } public float ConicWeight() { return SkiaApi.sk_path_rawiter_conic_weight(Handle); } public SKPathVerb Peek() { return SkiaApi.sk_path_rawiter_peek(Handle); } } public class OpBuilder : SKObject, ISKSkipObjectRegistration { public OpBuilder() : base(SkiaApi.sk_opbuilder_new(), owns: true) { } public void Add(SKPath path, SKPathOp op) { SkiaApi.sk_opbuilder_add(Handle, path.Handle, op); } public bool Resolve(SKPath result) { if (result == null) { throw new ArgumentNullException("result"); } return SkiaApi.sk_opbuilder_resolve(Handle, result.Handle); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_opbuilder_destroy(Handle); } } public SKPathFillType FillType { get { return SkiaApi.sk_path_get_filltype(Handle); } set { SkiaApi.sk_path_set_filltype(Handle, value); } } public SKPathConvexity Convexity { get { if (!IsConvex) { return SKPathConvexity.Concave; } return SKPathConvexity.Convex; } [Obsolete] set { } } public bool IsConvex => SkiaApi.sk_path_is_convex(Handle); public bool IsConcave => !IsConvex; public bool IsEmpty => VerbCount == 0; public unsafe bool IsOval => SkiaApi.sk_path_is_oval(Handle, null); public bool IsRoundRect => SkiaApi.sk_path_is_rrect(Handle, IntPtr.Zero); public unsafe bool IsLine => SkiaApi.sk_path_is_line(Handle, null); public unsafe bool IsRect => SkiaApi.sk_path_is_rect(Handle, null, null, null); public SKPathSegmentMask SegmentMasks => (SKPathSegmentMask)SkiaApi.sk_path_get_segment_masks(Handle); public int VerbCount => SkiaApi.sk_path_count_verbs(Handle); public int PointCount => SkiaApi.sk_path_count_points(Handle); public SKPoint this[int index] => GetPoint(index); public SKPoint[] Points => GetPoints(PointCount); public unsafe SKPoint LastPoint { get { SKPoint result = default(SKPoint); SkiaApi.sk_path_get_last_point(Handle, &result); return result; } } public unsafe SKRect Bounds { get { SKRect result = default(SKRect); SkiaApi.sk_path_get_bounds(Handle, &result); return result; } } public SKRect TightBounds { get { if (GetTightBounds(out var result)) { return result; } return SKRect.Empty; } } internal SKPath(IntPtr handle, bool owns) : base(handle, owns) { } public SKPath() : this(SkiaApi.sk_path_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPath instance."); } } public SKPath(SKPath path) : this(SkiaApi.sk_path_clone(path.Handle), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to copy the SKPath instance."); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_path_delete(Handle); } public unsafe SKRect GetOvalBounds() { SKRect result = default(SKRect); if (SkiaApi.sk_path_is_oval(Handle, &result)) { return result; } return SKRect.Empty; } public SKRoundRect GetRoundRect() { SKRoundRect sKRoundRect = new SKRoundRect(); if (SkiaApi.sk_path_is_rrect(Handle, sKRoundRect.Handle)) { return sKRoundRect; } sKRoundRect.Dispose(); return null; } public unsafe SKPoint[] GetLine() { SKPoint[] array = new SKPoint[2]; fixed (SKPoint* line = array) { if (SkiaApi.sk_path_is_line(Handle, line)) { return array; } return null; } } public SKRect GetRect() { bool isClosed; SKPathDirection direction; return GetRect(out isClosed, out direction); } public unsafe SKRect GetRect(out bool isClosed, out SKPathDirection direction) { fixed (SKPathDirection* direction2 = &direction) { SKRect result = default(SKRect); byte b = default(byte); bool flag = SkiaApi.sk_path_is_rect(Handle, &result, &b, direction2); isClosed = b > 0; if (flag) { return result; } return SKRect.Empty; } } public unsafe SKPoint GetPoint(int index) { if (index < 0 || index >= PointCount) { throw new ArgumentOutOfRangeException("index"); } SKPoint result = default(SKPoint); SkiaApi.sk_path_get_point(Handle, index, &result); return result; } public SKPoint[] GetPoints(int max) { SKPoint[] array = new SKPoint[max]; GetPoints(array, max); return array; } public unsafe int GetPoints(SKPoint[] points, int max) { fixed (SKPoint* points2 = points) { return SkiaApi.sk_path_get_points(Handle, points2, max); } } public bool Contains(float x, float y) { return SkiaApi.sk_path_contains(Handle, x, y); } public void Offset(SKPoint offset) { Offset(offset.X, offset.Y); } public void Offset(float dx, float dy) { Transform(SKMatrix.CreateTranslation(dx, dy)); } public void MoveTo(SKPoint point) { SkiaApi.sk_path_move_to(Handle, point.X, point.Y); } public void MoveTo(float x, float y) { SkiaApi.sk_path_move_to(Handle, x, y); } public void RMoveTo(SKPoint point) { SkiaApi.sk_path_rmove_to(Handle, point.X, point.Y); } public void RMoveTo(float dx, float dy) { SkiaApi.sk_path_rmove_to(Handle, dx, dy); } public void LineTo(SKPoint point) { SkiaApi.sk_path_line_to(Handle, point.X, point.Y); } public void LineTo(float x, float y) { SkiaApi.sk_path_line_to(Handle, x, y); } public void RLineTo(SKPoint point) { SkiaApi.sk_path_rline_to(Handle, point.X, point.Y); } public void RLineTo(float dx, float dy) { SkiaApi.sk_path_rline_to(Handle, dx, dy); } public void QuadTo(SKPoint point0, SKPoint point1) { SkiaApi.sk_path_quad_to(Handle, point0.X, point0.Y, point1.X, point1.Y); } public void QuadTo(float x0, float y0, float x1, float y1) { SkiaApi.sk_path_quad_to(Handle, x0, y0, x1, y1); } public void RQuadTo(SKPoint point0, SKPoint point1) { SkiaApi.sk_path_rquad_to(Handle, point0.X, point0.Y, point1.X, point1.Y); } public void RQuadTo(float dx0, float dy0, float dx1, float dy1) { SkiaApi.sk_path_rquad_to(Handle, dx0, dy0, dx1, dy1); } public void ConicTo(SKPoint point0, SKPoint point1, float w) { SkiaApi.sk_path_conic_to(Handle, point0.X, point0.Y, point1.X, point1.Y, w); } public void ConicTo(float x0, float y0, float x1, float y1, float w) { SkiaApi.sk_path_conic_to(Handle, x0, y0, x1, y1, w); } public void RConicTo(SKPoint point0, SKPoint point1, float w) { SkiaApi.sk_path_rconic_to(Handle, point0.X, point0.Y, point1.X, point1.Y, w); } public void RConicTo(float dx0, float dy0, float dx1, float dy1, float w) { SkiaApi.sk_path_rconic_to(Handle, dx0, dy0, dx1, dy1, w); } public void CubicTo(SKPoint point0, SKPoint point1, SKPoint point2) { SkiaApi.sk_path_cubic_to(Handle, point0.X, point0.Y, point1.X, point1.Y, point2.X, point2.Y); } public void CubicTo(float x0, float y0, float x1, float y1, float x2, float y2) { SkiaApi.sk_path_cubic_to(Handle, x0, y0, x1, y1, x2, y2); } public void RCubicTo(SKPoint point0, SKPoint point1, SKPoint point2) { SkiaApi.sk_path_rcubic_to(Handle, point0.X, point0.Y, point1.X, point1.Y, point2.X, point2.Y); } public void RCubicTo(float dx0, float dy0, float dx1, float dy1, float dx2, float dy2) { SkiaApi.sk_path_rcubic_to(Handle, dx0, dy0, dx1, dy1, dx2, dy2); } public void ArcTo(SKPoint r, float xAxisRotate, SKPathArcSize largeArc, SKPathDirection sweep, SKPoint xy) { SkiaApi.sk_path_arc_to(Handle, r.X, r.Y, xAxisRotate, largeArc, sweep, xy.X, xy.Y); } public void ArcTo(float rx, float ry, float xAxisRotate, SKPathArcSize largeArc, SKPathDirection sweep, float x, float y) { SkiaApi.sk_path_arc_to(Handle, rx, ry, xAxisRotate, largeArc, sweep, x, y); } public unsafe void ArcTo(SKRect oval, float startAngle, float sweepAngle, bool forceMoveTo) { SkiaApi.sk_path_arc_to_with_oval(Handle, &oval, startAngle, sweepAngle, forceMoveTo); } public void ArcTo(SKPoint point1, SKPoint point2, float radius) { SkiaApi.sk_path_arc_to_with_points(Handle, point1.X, point1.Y, point2.X, point2.Y, radius); } public void ArcTo(float x1, float y1, float x2, float y2, float radius) { SkiaApi.sk_path_arc_to_with_points(Handle, x1, y1, x2, y2, radius); } public void RArcTo(SKPoint r, float xAxisRotate, SKPathArcSize largeArc, SKPathDirection sweep, SKPoint xy) { SkiaApi.sk_path_rarc_to(Handle, r.X, r.Y, xAxisRotate, largeArc, sweep, xy.X, xy.Y); } public void RArcTo(float rx, float ry, float xAxisRotate, SKPathArcSize largeArc, SKPathDirection sweep, float x, float y) { SkiaApi.sk_path_rarc_to(Handle, rx, ry, xAxisRotate, largeArc, sweep, x, y); } public void Close() { SkiaApi.sk_path_close(Handle); } public void Rewind() { SkiaApi.sk_path_rewind(Handle); } public void Reset() { SkiaApi.sk_path_reset(Handle); } public unsafe void AddRect(SKRect rect, SKPathDirection direction = SKPathDirection.Clockwise) { SkiaApi.sk_path_add_rect(Handle, &rect, direction); } public unsafe void AddRect(SKRect rect, SKPathDirection direction, uint startIndex) { if (startIndex > 3) { throw new ArgumentOutOfRangeException("startIndex", "Starting index must be in the range of 0..3 (inclusive)."); } SkiaApi.sk_path_add_rect_start(Handle, &rect, direction, startIndex); } public void AddRoundRect(SKRoundRect rect, SKPathDirection direction = SKPathDirection.Clockwise) { if (rect == null) { throw new ArgumentNullException("rect"); } SkiaApi.sk_path_add_rrect(Handle, rect.Handle, direction); } public void AddRoundRect(SKRoundRect rect, SKPathDirection direction, uint startIndex) { if (rect == null) { throw new ArgumentNullException("rect"); } SkiaApi.sk_path_add_rrect_start(Handle, rect.Handle, direction, startIndex); } public unsafe void AddOval(SKRect rect, SKPathDirection direction = SKPathDirection.Clockwise) { SkiaApi.sk_path_add_oval(Handle, &rect, direction); } public unsafe void AddArc(SKRect oval, float startAngle, float sweepAngle) { SkiaApi.sk_path_add_arc(Handle, &oval, startAngle, sweepAngle); } public unsafe bool GetBounds(out SKRect rect) { bool isEmpty = IsEmpty; if (isEmpty) { rect = SKRect.Empty; } else { fixed (SKRect* param = &rect) { SkiaApi.sk_path_get_bounds(Handle, param); } } return !isEmpty; } public unsafe SKRect ComputeTightBounds() { SKRect result = default(SKRect); SkiaApi.sk_path_compute_tight_bounds(Handle, &result); return result; } public unsafe void Transform(SKMatrix matrix) { SkiaApi.sk_path_transform(Handle, &matrix); } public unsafe void Transform(SKMatrix matrix, SKPath destination) { if (destination == null) { throw new ArgumentNullException("destination"); } SkiaApi.sk_path_transform_to_dest(Handle, &matrix, destination.Handle); } public void AddPath(SKPath other, float dx, float dy, SKPathAddMode mode = SKPathAddMode.Append) { if (other == null) { throw new ArgumentNullException("other"); } SkiaApi.sk_path_add_path_offset(Handle, other.Handle, dx, dy, mode); } public unsafe void AddPath(SKPath other, ref SKMatrix matrix, SKPathAddMode mode = SKPathAddMode.Append) { if (other == null) { throw new ArgumentNullException("other"); } fixed (SKMatrix* matrix2 = &matrix) { SkiaApi.sk_path_add_path_matrix(Handle, other.Handle, matrix2, mode); } } public void AddPath(SKPath other, SKPathAddMode mode = SKPathAddMode.Append) { if (other == null) { throw new ArgumentNullException("other"); } SkiaApi.sk_path_add_path(Handle, other.Handle, mode); } public void AddPathReverse(SKPath other) { if (other == null) { throw new ArgumentNullException("other"); } SkiaApi.sk_path_add_path_reverse(Handle, other.Handle); } public unsafe void AddRoundRect(SKRect rect, float rx, float ry, SKPathDirection dir = SKPathDirection.Clockwise) { SkiaApi.sk_path_add_rounded_rect(Handle, &rect, rx, ry, dir); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRoundRect instead.")] public void AddRoundedRect(SKRect rect, float rx, float ry, SKPathDirection dir = SKPathDirection.Clockwise) { AddRoundRect(rect, rx, ry, dir); } public void AddCircle(float x, float y, float radius, SKPathDirection dir = SKPathDirection.Clockwise) { SkiaApi.sk_path_add_circle(Handle, x, y, radius, dir); } public unsafe void AddPoly(SKPoint[] points, bool close = true) { if (points == null) { throw new ArgumentNullException("points"); } fixed (SKPoint* points2 = points) { SkiaApi.sk_path_add_poly(Handle, points2, points.Length, close); } } public Iterator CreateIterator(bool forceClose) { return new Iterator(this, forceClose); } public RawIterator CreateRawIterator() { return new RawIterator(this); } public bool Op(SKPath other, SKPathOp op, SKPath result) { if (other == null) { throw new ArgumentNullException("other"); } if (result == null) { throw new ArgumentNullException("result"); } return SkiaApi.sk_pathop_op(Handle, other.Handle, op, result.Handle); } public SKPath Op(SKPath other, SKPathOp op) { SKPath sKPath = new SKPath(); if (Op(other, op, sKPath)) { return sKPath; } sKPath.Dispose(); return null; } public bool Simplify(SKPath result) { if (result == null) { throw new ArgumentNullException("result"); } return SkiaApi.sk_pathop_simplify(Handle, result.Handle); } public SKPath Simplify() { SKPath sKPath = new SKPath(); if (Simplify(sKPath)) { return sKPath; } sKPath.Dispose(); return null; } public unsafe bool GetTightBounds(out SKRect result) { fixed (SKRect* result2 = &result) { return SkiaApi.sk_pathop_tight_bounds(Handle, result2); } } public bool ToWinding(SKPath result) { if (result == null) { throw new ArgumentNullException("result"); } return SkiaApi.sk_pathop_as_winding(Handle, result.Handle); } public SKPath ToWinding() { SKPath sKPath = new SKPath(); if (ToWinding(sKPath)) { return sKPath; } sKPath.Dispose(); return null; } public string ToSvgPathData() { using SKString sKString = new SKString(); SkiaApi.sk_path_to_svg_string(Handle, sKString.Handle); return (string)sKString; } public static SKPath ParseSvgPathData(string svgPath) { SKPath sKPath = new SKPath(); if (!SkiaApi.sk_path_parse_svg_string(sKPath.Handle, svgPath)) { sKPath.Dispose(); sKPath = null; } return sKPath; } public static SKPoint[] ConvertConicToQuads(SKPoint p0, SKPoint p1, SKPoint p2, float w, int pow2) { ConvertConicToQuads(p0, p1, p2, w, out var pts, pow2); return pts; } public static int ConvertConicToQuads(SKPoint p0, SKPoint p1, SKPoint p2, float w, out SKPoint[] pts, int pow2) { int num = 1 << pow2; int num2 = 2 * num + 1; pts = new SKPoint[num2]; return ConvertConicToQuads(p0, p1, p2, w, pts, pow2); } public unsafe static int ConvertConicToQuads(SKPoint p0, SKPoint p1, SKPoint p2, float w, SKPoint[] pts, int pow2) { if (pts == null) { throw new ArgumentNullException("pts"); } fixed (SKPoint* pts2 = pts) { return SkiaApi.sk_path_convert_conic_to_quads(&p0, &p1, &p2, w, pts2, pow2); } } internal static SKPath GetObject(IntPtr handle, bool owns = true) { if (!(handle == IntPtr.Zero)) { return new SKPath(handle, owns); } return null; } } public class SKPathEffect : SKObject, ISKReferenceCounted { internal SKPathEffect(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public static SKPathEffect CreateCompose(SKPathEffect outer, SKPathEffect inner) { if (outer == null) { throw new ArgumentNullException("outer"); } if (inner == null) { throw new ArgumentNullException("inner"); } return GetObject(SkiaApi.sk_path_effect_create_compose(outer.Handle, inner.Handle)); } public static SKPathEffect CreateSum(SKPathEffect first, SKPathEffect second) { if (first == null) { throw new ArgumentNullException("first"); } if (second == null) { throw new ArgumentNullException("second"); } return GetObject(SkiaApi.sk_path_effect_create_sum(first.Handle, second.Handle)); } public static SKPathEffect CreateDiscrete(float segLength, float deviation, uint seedAssist = 0u) { return GetObject(SkiaApi.sk_path_effect_create_discrete(segLength, deviation, seedAssist)); } public static SKPathEffect CreateCorner(float radius) { return GetObject(SkiaApi.sk_path_effect_create_corner(radius)); } public static SKPathEffect Create1DPath(SKPath path, float advance, float phase, SKPath1DPathEffectStyle style) { if (path == null) { throw new ArgumentNullException("path"); } return GetObject(SkiaApi.sk_path_effect_create_1d_path(path.Handle, advance, phase, style)); } public unsafe static SKPathEffect Create2DLine(float width, SKMatrix matrix) { return GetObject(SkiaApi.sk_path_effect_create_2d_line(width, &matrix)); } public unsafe static SKPathEffect Create2DPath(SKMatrix matrix, SKPath path) { if (path == null) { throw new ArgumentNullException("path"); } return GetObject(SkiaApi.sk_path_effect_create_2d_path(&matrix, path.Handle)); } public unsafe static SKPathEffect CreateDash(float[] intervals, float phase) { if (intervals == null) { throw new ArgumentNullException("intervals"); } if (intervals.Length % 2 != 0) { throw new ArgumentException("The intervals must have an even number of entries.", "intervals"); } fixed (float* intervals2 = intervals) { return GetObject(SkiaApi.sk_path_effect_create_dash(intervals2, intervals.Length, phase)); } } public static SKPathEffect CreateTrim(float start, float stop) { return CreateTrim(start, stop, SKTrimPathEffectMode.Normal); } public static SKPathEffect CreateTrim(float start, float stop, SKTrimPathEffectMode mode) { return GetObject(SkiaApi.sk_path_effect_create_trim(start, stop, mode)); } internal static SKPathEffect GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKPathEffect(h, o)); } } public class SKPathMeasure : SKObject, ISKSkipObjectRegistration { public float Length => SkiaApi.sk_pathmeasure_get_length(Handle); public bool IsClosed => SkiaApi.sk_pathmeasure_is_closed(Handle); internal SKPathMeasure(IntPtr handle, bool owns) : base(handle, owns) { } public SKPathMeasure() : this(SkiaApi.sk_pathmeasure_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPathMeasure instance."); } } public SKPathMeasure(SKPath path, bool forceClosed = false, float resScale = 1f) : this(IntPtr.Zero, owns: true) { if (path == null) { throw new ArgumentNullException("path"); } Handle = SkiaApi.sk_pathmeasure_new_with_path(path.Handle, forceClosed, resScale); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPathMeasure instance."); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_pathmeasure_destroy(Handle); } public void SetPath(SKPath path) { SetPath(path, forceClosed: false); } public void SetPath(SKPath path, bool forceClosed) { SkiaApi.sk_pathmeasure_set_path(Handle, path?.Handle ?? IntPtr.Zero, forceClosed); } public unsafe bool GetPositionAndTangent(float distance, out SKPoint position, out SKPoint tangent) { fixed (SKPoint* position2 = &position) { fixed (SKPoint* tangent2 = &tangent) { return SkiaApi.sk_pathmeasure_get_pos_tan(Handle, distance, position2, tangent2); } } } public SKPoint GetPosition(float distance) { if (!GetPosition(distance, out var position)) { return SKPoint.Empty; } return position; } public unsafe bool GetPosition(float distance, out SKPoint position) { fixed (SKPoint* position2 = &position) { return SkiaApi.sk_pathmeasure_get_pos_tan(Handle, distance, position2, null); } } public SKPoint GetTangent(float distance) { if (!GetTangent(distance, out var tangent)) { return SKPoint.Empty; } return tangent; } public unsafe bool GetTangent(float distance, out SKPoint tangent) { fixed (SKPoint* tangent2 = &tangent) { return SkiaApi.sk_pathmeasure_get_pos_tan(Handle, distance, null, tangent2); } } public SKMatrix GetMatrix(float distance, SKPathMeasureMatrixFlags flags) { if (!GetMatrix(distance, out var matrix, flags)) { return SKMatrix.Empty; } return matrix; } public unsafe bool GetMatrix(float distance, out SKMatrix matrix, SKPathMeasureMatrixFlags flags) { fixed (SKMatrix* matrix2 = &matrix) { return SkiaApi.sk_pathmeasure_get_matrix(Handle, distance, matrix2, flags); } } public bool GetSegment(float start, float stop, SKPath dst, bool startWithMoveTo) { if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_pathmeasure_get_segment(Handle, start, stop, dst.Handle, startWithMoveTo); } public SKPath GetSegment(float start, float stop, bool startWithMoveTo) { SKPath sKPath = new SKPath(); if (!GetSegment(start, stop, sKPath, startWithMoveTo)) { sKPath.Dispose(); sKPath = null; } return sKPath; } public bool NextContour() { return SkiaApi.sk_pathmeasure_next_contour(Handle); } } public class SKPicture : SKObject, ISKReferenceCounted { public uint UniqueId => SkiaApi.sk_picture_get_unique_id(Handle); public unsafe SKRect CullRect { get { SKRect result = default(SKRect); SkiaApi.sk_picture_get_cull_rect(Handle, &result); return result; } } internal SKPicture(IntPtr h, bool owns) : base(h, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public SKData Serialize() { return SKData.GetObject(SkiaApi.sk_picture_serialize_to_data(Handle)); } public void Serialize(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKManagedWStream stream2 = new SKManagedWStream(stream); Serialize(stream2); } public void Serialize(SKWStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } SkiaApi.sk_picture_serialize_to_stream(Handle, stream.Handle); } public SKShader ToShader() { return ToShader(SKShaderTileMode.Clamp, SKShaderTileMode.Clamp); } public unsafe SKShader ToShader(SKShaderTileMode tmx, SKShaderTileMode tmy) { return SKShader.GetObject(SkiaApi.sk_picture_make_shader(Handle, tmx, tmy, null, null)); } public unsafe SKShader ToShader(SKShaderTileMode tmx, SKShaderTileMode tmy, SKRect tile) { return SKShader.GetObject(SkiaApi.sk_picture_make_shader(Handle, tmx, tmy, null, &tile)); } public unsafe SKShader ToShader(SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix, SKRect tile) { return SKShader.GetObject(SkiaApi.sk_picture_make_shader(Handle, tmx, tmy, &localMatrix, &tile)); } public unsafe static SKPicture Deserialize(IntPtr data, int length) { if (data == IntPtr.Zero) { throw new ArgumentNullException("data"); } if (length == 0) { return null; } return GetObject(SkiaApi.sk_picture_deserialize_from_memory((void*)data, (IntPtr)length)); } public unsafe static SKPicture Deserialize(ReadOnlySpan data) { if (data.Length == 0) { return null; } fixed (byte* ptr = data) { void* buffer = ptr; return GetObject(SkiaApi.sk_picture_deserialize_from_memory(buffer, (IntPtr)data.Length)); } } public static SKPicture Deserialize(SKData data) { if (data == null) { throw new ArgumentNullException("data"); } return GetObject(SkiaApi.sk_picture_deserialize_from_data(data.Handle)); } public static SKPicture Deserialize(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } using SKManagedStream stream2 = new SKManagedStream(stream); return Deserialize(stream2); } public static SKPicture Deserialize(SKStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } return GetObject(SkiaApi.sk_picture_deserialize_from_stream(stream.Handle)); } internal static SKPicture GetObject(IntPtr handle, bool owns = true, bool unrefExisting = true) { return SKObject.GetOrAddObject(handle, owns, unrefExisting, (IntPtr h, bool o) => new SKPicture(h, o)); } } public class SKPictureRecorder : SKObject, ISKSkipObjectRegistration { public SKCanvas RecordingCanvas => SKObject.OwnedBy(SKCanvas.GetObject(SkiaApi.sk_picture_get_recording_canvas(Handle), owns: false), this); internal SKPictureRecorder(IntPtr handle, bool owns) : base(handle, owns) { } public SKPictureRecorder() : this(SkiaApi.sk_picture_recorder_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPictureRecorder instance."); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_picture_recorder_delete(Handle); } public unsafe SKCanvas BeginRecording(SKRect cullRect) { return SKObject.OwnedBy(SKCanvas.GetObject(SkiaApi.sk_picture_recorder_begin_recording(Handle, &cullRect), owns: false), this); } public SKPicture EndRecording() { return SKPicture.GetObject(SkiaApi.sk_picture_recorder_end_recording(Handle)); } public SKDrawable EndRecordingAsDrawable() { return SKDrawable.GetObject(SkiaApi.sk_picture_recorder_end_recording_as_drawable(Handle)); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public abstract class SKPixelSerializer : SKObject, ISKSkipObjectRegistration { protected SKPixelSerializer() : base(IntPtr.Zero, owns: false) { } public bool UseEncodedData(IntPtr data, ulong length) { if (!PlatformConfiguration.Is64Bit && length > uint.MaxValue) { throw new ArgumentOutOfRangeException("length", "The length exceeds the size of pointers."); } return OnUseEncodedData(data, (IntPtr)(long)length); } public SKData Encode(SKPixmap pixmap) { if (pixmap == null) { throw new ArgumentNullException("pixmap"); } return OnEncode(pixmap); } protected abstract bool OnUseEncodedData(IntPtr data, IntPtr length); protected abstract SKData OnEncode(SKPixmap pixmap); public static SKPixelSerializer Create(Func onEncode) { return new SKSimplePixelSerializer(null, onEncode); } public static SKPixelSerializer Create(Func onUseEncodedData, Func onEncode) { return new SKSimplePixelSerializer(onUseEncodedData, onEncode); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] internal class SKSimplePixelSerializer : SKPixelSerializer { private readonly Func onUseEncodedData; private readonly Func onEncode; public SKSimplePixelSerializer(Func onUseEncodedData, Func onEncode) { this.onUseEncodedData = onUseEncodedData; this.onEncode = onEncode; } protected override SKData OnEncode(SKPixmap pixmap) { return onEncode?.Invoke(pixmap) ?? null; } protected override bool OnUseEncodedData(IntPtr data, IntPtr length) { return onUseEncodedData?.Invoke(data, length) ?? false; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public abstract class SKManagedPixelSerializer : SKPixelSerializer { public SKManagedPixelSerializer() { } } public class SKPixmap : SKObject { private const string UnableToCreateInstanceMessage = "Unable to create a new SKPixmap instance."; internal SKObject pixelSource; public unsafe SKImageInfo Info { get { SKImageInfoNative native = default(SKImageInfoNative); SkiaApi.sk_pixmap_get_info(Handle, &native); return SKImageInfoNative.ToManaged(ref native); } } public int Width => Info.Width; public int Height => Info.Height; public SKSizeI Size { get { SKImageInfo info = Info; return new SKSizeI(info.Width, info.Height); } } public SKRectI Rect => SKRectI.Create(Size); public SKColorType ColorType => Info.ColorType; public SKAlphaType AlphaType => Info.AlphaType; public SKColorSpace ColorSpace => Info.ColorSpace; public int BytesPerPixel => Info.BytesPerPixel; public int RowBytes => (int)SkiaApi.sk_pixmap_get_row_bytes(Handle); public int BytesSize => Info.BytesSize; [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported.")] public SKColorTable ColorTable => null; internal SKPixmap(IntPtr handle, bool owns) : base(handle, owns) { } public SKPixmap() : this(SkiaApi.sk_pixmap_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPixmap instance."); } } public SKPixmap(SKImageInfo info, IntPtr addr) : this(info, addr, info.RowBytes) { } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use SKPixmap(SKImageInfo, IntPtr, int) instead.")] public SKPixmap(SKImageInfo info, IntPtr addr, int rowBytes, SKColorTable ctable) : this(info, addr, info.RowBytes) { } public unsafe SKPixmap(SKImageInfo info, IntPtr addr, int rowBytes) : this(IntPtr.Zero, owns: true) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); Handle = SkiaApi.sk_pixmap_new_with_params(&sKImageInfoNative, (void*)addr, (IntPtr)rowBytes); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPixmap instance."); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_pixmap_destructor(Handle); } protected override void DisposeManaged() { base.DisposeManaged(); pixelSource = null; } public void Reset() { SkiaApi.sk_pixmap_reset(Handle); pixelSource = null; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("The Index8 color type and color table is no longer supported. Use Reset(SKImageInfo, IntPtr, int) instead.")] public void Reset(SKImageInfo info, IntPtr addr, int rowBytes, SKColorTable ctable) { Reset(info, addr, rowBytes); } public unsafe void Reset(SKImageInfo info, IntPtr addr, int rowBytes) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); SkiaApi.sk_pixmap_reset_with_params(Handle, &sKImageInfoNative, (void*)addr, (IntPtr)rowBytes); pixelSource = null; } public unsafe IntPtr GetPixels() { return (IntPtr)SkiaApi.sk_pixmap_get_pixels(Handle); } public unsafe IntPtr GetPixels(int x, int y) { return (IntPtr)SkiaApi.sk_pixmap_get_pixels_with_xy(Handle, x, y); } public unsafe ReadOnlySpan GetPixelSpan() { return new ReadOnlySpan(SkiaApi.sk_pixmap_get_pixels(Handle), BytesSize); } public unsafe Span GetPixelSpan() where T : unmanaged { SKImageInfo info = Info; if (info.IsEmpty) { return null; } int bytesPerPixel = info.BytesPerPixel; if (bytesPerPixel <= 0) { return null; } if (typeof(T) == typeof(byte)) { return new Span(SkiaApi.sk_pixmap_get_writable_addr(Handle), info.BytesSize); } int num = sizeof(T); if (bytesPerPixel != num) { throw new ArgumentException($"Size of T ({num}) is not the same as the size of each pixel ({bytesPerPixel}).", "T"); } return new Span(SkiaApi.sk_pixmap_get_writable_addr(Handle), info.Width * info.Height); } public SKColor GetPixelColor(int x, int y) { return SkiaApi.sk_pixmap_get_pixel_color(Handle, x, y); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ScalePixels(SKPixmap, SKFilterQuality) instead.")] public static bool Resize(SKPixmap dst, SKPixmap src, SKBitmapResizeMethod method) { if (dst == null) { throw new ArgumentNullException("dst"); } if (src == null) { throw new ArgumentNullException("src"); } return src.ScalePixels(dst, method.ToFilterQuality()); } public bool ScalePixels(SKPixmap destination, SKFilterQuality quality) { if (destination == null) { throw new ArgumentNullException("destination"); } return SkiaApi.sk_pixmap_scale_pixels(Handle, destination.Handle, quality); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ReadPixels(SKImageInfo, IntPtr, int, int, int) instead.")] public bool ReadPixels(SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY, SKTransferFunctionBehavior behavior) { return ReadPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY); } public unsafe bool ReadPixels(SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref dstInfo); return SkiaApi.sk_pixmap_read_pixels(Handle, &sKImageInfoNative, (void*)dstPixels, (IntPtr)dstRowBytes, srcX, srcY); } public bool ReadPixels(SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes) { return ReadPixels(dstInfo, dstPixels, dstRowBytes, 0, 0); } public bool ReadPixels(SKPixmap pixmap, int srcX, int srcY) { return ReadPixels(pixmap.Info, pixmap.GetPixels(), pixmap.RowBytes, srcX, srcY); } public bool ReadPixels(SKPixmap pixmap) { return ReadPixels(pixmap.Info, pixmap.GetPixels(), pixmap.RowBytes, 0, 0); } public SKData Encode(SKEncodedImageFormat encoder, int quality) { using SKDynamicMemoryWStream sKDynamicMemoryWStream = new SKDynamicMemoryWStream(); return Encode(sKDynamicMemoryWStream, encoder, quality) ? sKDynamicMemoryWStream.DetachAsData() : null; } public bool Encode(Stream dst, SKEncodedImageFormat encoder, int quality) { if (dst == null) { throw new ArgumentNullException("dst"); } using SKManagedWStream dst2 = new SKManagedWStream(dst); return Encode(dst2, encoder, quality); } public bool Encode(SKWStream dst, SKEncodedImageFormat encoder, int quality) { if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_pixmap_encode_image(dst.Handle, Handle, encoder, quality); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Encode(SKWStream, SKEncodedImageFormat, int) instead.")] public static bool Encode(SKWStream dst, SKBitmap src, SKEncodedImageFormat format, int quality) { if (dst == null) { throw new ArgumentNullException("dst"); } if (src == null) { throw new ArgumentNullException("src"); } return src.Encode(dst, format, quality); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Encode(SKWStream, SKEncodedImageFormat, int) instead.")] public static bool Encode(SKWStream dst, SKPixmap src, SKEncodedImageFormat encoder, int quality) { if (dst == null) { throw new ArgumentNullException("dst"); } if (src == null) { throw new ArgumentNullException("src"); } return src.Encode(dst, encoder, quality); } public SKData Encode(SKWebpEncoderOptions options) { using SKDynamicMemoryWStream sKDynamicMemoryWStream = new SKDynamicMemoryWStream(); return Encode(sKDynamicMemoryWStream, options) ? sKDynamicMemoryWStream.DetachAsData() : null; } public bool Encode(Stream dst, SKWebpEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } using SKManagedWStream dst2 = new SKManagedWStream(dst); return Encode(dst2, options); } public unsafe bool Encode(SKWStream dst, SKWebpEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_webpencoder_encode(dst.Handle, Handle, &options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Encode(SKWStream, SKWebpEncoderOptions) instead.")] public static bool Encode(SKWStream dst, SKPixmap src, SKWebpEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } if (src == null) { throw new ArgumentNullException("src"); } return src.Encode(dst, options); } public SKData Encode(SKJpegEncoderOptions options) { using SKDynamicMemoryWStream sKDynamicMemoryWStream = new SKDynamicMemoryWStream(); return Encode(sKDynamicMemoryWStream, options) ? sKDynamicMemoryWStream.DetachAsData() : null; } public bool Encode(Stream dst, SKJpegEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } using SKManagedWStream dst2 = new SKManagedWStream(dst); return Encode(dst2, options); } public unsafe bool Encode(SKWStream dst, SKJpegEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_jpegencoder_encode(dst.Handle, Handle, &options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Encode(SKWStream, SKJpegEncoderOptions) instead.")] public static bool Encode(SKWStream dst, SKPixmap src, SKJpegEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } if (src == null) { throw new ArgumentNullException("src"); } return src.Encode(dst, options); } public SKData Encode(SKPngEncoderOptions options) { using SKDynamicMemoryWStream sKDynamicMemoryWStream = new SKDynamicMemoryWStream(); return Encode(sKDynamicMemoryWStream, options) ? sKDynamicMemoryWStream.DetachAsData() : null; } public bool Encode(Stream dst, SKPngEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } using SKManagedWStream dst2 = new SKManagedWStream(dst); return Encode(dst2, options); } public unsafe bool Encode(SKWStream dst, SKPngEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_pngencoder_encode(dst.Handle, Handle, &options); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Encode(SKWStream, SKPngEncoderOptions) instead.")] public static bool Encode(SKWStream dst, SKPixmap src, SKPngEncoderOptions options) { if (dst == null) { throw new ArgumentNullException("dst"); } if (src == null) { throw new ArgumentNullException("src"); } return src.Encode(dst, options); } public SKPixmap ExtractSubset(SKRectI subset) { SKPixmap sKPixmap = new SKPixmap(); if (!ExtractSubset(sKPixmap, subset)) { sKPixmap.Dispose(); sKPixmap = null; } return sKPixmap; } public unsafe bool ExtractSubset(SKPixmap result, SKRectI subset) { if (result == null) { throw new ArgumentNullException("result"); } return SkiaApi.sk_pixmap_extract_subset(Handle, result.Handle, &subset); } public bool Erase(SKColor color) { return Erase(color, Rect); } public unsafe bool Erase(SKColor color, SKRectI subset) { return SkiaApi.sk_pixmap_erase_color(Handle, (uint)color, &subset); } public bool Erase(SKColorF color) { return Erase(color, null, Rect); } public bool Erase(SKColorF color, SKRectI subset) { return Erase(color, null, subset); } public unsafe bool Erase(SKColorF color, SKColorSpace colorspace, SKRectI subset) { return SkiaApi.sk_pixmap_erase_color4f(Handle, &color, colorspace?.Handle ?? IntPtr.Zero, &subset); } public SKPixmap WithColorType(SKColorType newColorType) { return new SKPixmap(Info.WithColorType(newColorType), GetPixels(), RowBytes); } public SKPixmap WithColorSpace(SKColorSpace newColorSpace) { return new SKPixmap(Info.WithColorSpace(newColorSpace), GetPixels(), RowBytes); } public SKPixmap WithAlphaType(SKAlphaType newAlphaType) { return new SKPixmap(Info.WithAlphaType(newAlphaType), GetPixels(), RowBytes); } } public readonly struct SKPMColor : IEquatable { private readonly uint color; public byte Alpha => (byte)((color >> SKImageInfo.PlatformColorAlphaShift) & 0xFF); public byte Red => (byte)((color >> SKImageInfo.PlatformColorRedShift) & 0xFF); public byte Green => (byte)((color >> SKImageInfo.PlatformColorGreenShift) & 0xFF); public byte Blue => (byte)((color >> SKImageInfo.PlatformColorBlueShift) & 0xFF); public SKPMColor(uint value) { color = value; } public static SKPMColor PreMultiply(SKColor color) { return SkiaApi.sk_color_premultiply((uint)color); } public unsafe static SKPMColor[] PreMultiply(SKColor[] colors) { SKPMColor[] array = new SKPMColor[colors.Length]; fixed (SKColor* colors2 = colors) { fixed (SKPMColor* pmcolors = array) { SkiaApi.sk_color_premultiply_array((uint*)colors2, colors.Length, (uint*)pmcolors); } } return array; } public static SKColor UnPreMultiply(SKPMColor pmcolor) { return SkiaApi.sk_color_unpremultiply((uint)pmcolor); } public unsafe static SKColor[] UnPreMultiply(SKPMColor[] pmcolors) { SKColor[] array = new SKColor[pmcolors.Length]; fixed (SKColor* colors = array) { fixed (SKPMColor* pmcolors2 = pmcolors) { SkiaApi.sk_color_unpremultiply_array((uint*)pmcolors2, pmcolors.Length, (uint*)colors); } } return array; } public static explicit operator SKPMColor(SKColor color) { return PreMultiply(color); } public static explicit operator SKColor(SKPMColor color) { return UnPreMultiply(color); } public override string ToString() { return $"#{Alpha:x2}{Red:x2}{Green:x2}{Blue:x2}"; } public bool Equals(SKPMColor obj) { return obj.color == color; } public override bool Equals(object other) { if (other is SKPMColor obj) { return Equals(obj); } return false; } public static bool operator ==(SKPMColor left, SKPMColor right) { return left.Equals(right); } public static bool operator !=(SKPMColor left, SKPMColor right) { return !left.Equals(right); } public override int GetHashCode() { uint num = color; return num.GetHashCode(); } public static implicit operator SKPMColor(uint color) { return new SKPMColor(color); } public static explicit operator uint(SKPMColor color) { return color.color; } } public class SKRegion : SKObject, ISKSkipObjectRegistration { public class RectIterator : SKObject, ISKSkipObjectRegistration { private readonly SKRegion region; internal RectIterator(SKRegion region) : base(SkiaApi.sk_region_iterator_new(region.Handle), owns: true) { this.region = region; } protected override void DisposeNative() { SkiaApi.sk_region_iterator_delete(Handle); } public unsafe bool Next(out SKRectI rect) { if (SkiaApi.sk_region_iterator_done(Handle)) { rect = SKRectI.Empty; return false; } fixed (SKRectI* rect2 = &rect) { SkiaApi.sk_region_iterator_rect(Handle, rect2); } SkiaApi.sk_region_iterator_next(Handle); return true; } } public class ClipIterator : SKObject, ISKSkipObjectRegistration { private readonly SKRegion region; private readonly SKRectI clip; internal unsafe ClipIterator(SKRegion region, SKRectI clip) : base(SkiaApi.sk_region_cliperator_new(region.Handle, &clip), owns: true) { this.region = region; this.clip = clip; } protected override void DisposeNative() { SkiaApi.sk_region_cliperator_delete(Handle); } public unsafe bool Next(out SKRectI rect) { if (SkiaApi.sk_region_cliperator_done(Handle)) { rect = SKRectI.Empty; return false; } fixed (SKRectI* rect2 = &rect) { SkiaApi.sk_region_iterator_rect(Handle, rect2); } SkiaApi.sk_region_cliperator_next(Handle); return true; } } public class SpanIterator : SKObject, ISKSkipObjectRegistration { internal SpanIterator(SKRegion region, int y, int left, int right) : base(SkiaApi.sk_region_spanerator_new(region.Handle, y, left, right), owns: true) { } protected override void DisposeNative() { SkiaApi.sk_region_spanerator_delete(Handle); } public unsafe bool Next(out int left, out int right) { int num = default(int); int num2 = default(int); if (SkiaApi.sk_region_spanerator_next(Handle, &num, &num2)) { left = num; right = num2; return true; } left = 0; right = 0; return false; } } public bool IsEmpty => SkiaApi.sk_region_is_empty(Handle); public bool IsRect => SkiaApi.sk_region_is_rect(Handle); public bool IsComplex => SkiaApi.sk_region_is_complex(Handle); public unsafe SKRectI Bounds { get { SKRectI result = default(SKRectI); SkiaApi.sk_region_get_bounds(Handle, &result); return result; } } internal SKRegion(IntPtr handle, bool owns) : base(handle, owns) { } public SKRegion() : this(SkiaApi.sk_region_new(), owns: true) { } public SKRegion(SKRegion region) : this() { SetRegion(region); } public SKRegion(SKRectI rect) : this() { SetRect(rect); } public SKRegion(SKPath path) : this() { SetPath(path); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_region_delete(Handle); } public SKPath GetBoundaryPath() { SKPath sKPath = new SKPath(); if (!SkiaApi.sk_region_get_boundary_path(Handle, sKPath.Handle)) { sKPath.Dispose(); sKPath = null; } return sKPath; } public bool Contains(SKPath path) { if (path == null) { throw new ArgumentNullException("path"); } using SKRegion src = new SKRegion(path); return Contains(src); } public bool Contains(SKRegion src) { if (src == null) { throw new ArgumentNullException("src"); } return SkiaApi.sk_region_contains(Handle, src.Handle); } public bool Contains(SKPointI xy) { return SkiaApi.sk_region_contains_point(Handle, xy.X, xy.Y); } public bool Contains(int x, int y) { return SkiaApi.sk_region_contains_point(Handle, x, y); } public unsafe bool Contains(SKRectI rect) { return SkiaApi.sk_region_contains_rect(Handle, &rect); } public unsafe bool QuickContains(SKRectI rect) { return SkiaApi.sk_region_quick_contains(Handle, &rect); } public unsafe bool QuickReject(SKRectI rect) { return SkiaApi.sk_region_quick_reject_rect(Handle, &rect); } public bool QuickReject(SKRegion region) { if (region == null) { throw new ArgumentNullException("region"); } return SkiaApi.sk_region_quick_reject(Handle, region.Handle); } public bool QuickReject(SKPath path) { if (path == null) { throw new ArgumentNullException("path"); } using SKRegion region = new SKRegion(path); return QuickReject(region); } public bool Intersects(SKPath path) { if (path == null) { throw new ArgumentNullException("path"); } using SKRegion region = new SKRegion(path); return Intersects(region); } public bool Intersects(SKRegion region) { if (region == null) { throw new ArgumentNullException("region"); } return SkiaApi.sk_region_intersects(Handle, region.Handle); } public unsafe bool Intersects(SKRectI rect) { return SkiaApi.sk_region_intersects_rect(Handle, &rect); } public void SetEmpty() { SkiaApi.sk_region_set_empty(Handle); } public bool SetRegion(SKRegion region) { if (region == null) { throw new ArgumentNullException("region"); } return SkiaApi.sk_region_set_region(Handle, region.Handle); } public unsafe bool SetRect(SKRectI rect) { return SkiaApi.sk_region_set_rect(Handle, &rect); } public unsafe bool SetRects(SKRectI[] rects) { if (rects == null) { throw new ArgumentNullException("rects"); } fixed (SKRectI* rects2 = rects) { return SkiaApi.sk_region_set_rects(Handle, rects2, rects.Length); } } public bool SetPath(SKPath path, SKRegion clip) { if (path == null) { throw new ArgumentNullException("path"); } if (clip == null) { throw new ArgumentNullException("clip"); } return SkiaApi.sk_region_set_path(Handle, path.Handle, clip.Handle); } public bool SetPath(SKPath path) { if (path == null) { throw new ArgumentNullException("path"); } using SKRegion sKRegion = new SKRegion(); SKRectI rect = SKRectI.Ceiling(path.Bounds); if (!rect.IsEmpty) { sKRegion.SetRect(rect); } return SkiaApi.sk_region_set_path(Handle, path.Handle, sKRegion.Handle); } public void Translate(int x, int y) { SkiaApi.sk_region_translate(Handle, x, y); } public unsafe bool Op(SKRectI rect, SKRegionOperation op) { return SkiaApi.sk_region_op_rect(Handle, &rect, op); } public bool Op(int left, int top, int right, int bottom, SKRegionOperation op) { return Op(new SKRectI(left, top, right, bottom), op); } public bool Op(SKRegion region, SKRegionOperation op) { return SkiaApi.sk_region_op(Handle, region.Handle, op); } public bool Op(SKPath path, SKRegionOperation op) { using SKRegion region = new SKRegion(path); return Op(region, op); } public RectIterator CreateRectIterator() { return new RectIterator(this); } public ClipIterator CreateClipIterator(SKRectI clip) { return new ClipIterator(this, clip); } public SpanIterator CreateSpanIterator(int y, int left, int right) { return new SpanIterator(this, y, left, right); } } public class SKRoundRect : SKObject, ISKSkipObjectRegistration { public unsafe SKRect Rect { get { SKRect result = default(SKRect); SkiaApi.sk_rrect_get_rect(Handle, &result); return result; } } public SKPoint[] Radii => new SKPoint[4] { GetRadii(SKRoundRectCorner.UpperLeft), GetRadii(SKRoundRectCorner.UpperRight), GetRadii(SKRoundRectCorner.LowerRight), GetRadii(SKRoundRectCorner.LowerLeft) }; public SKRoundRectType Type => SkiaApi.sk_rrect_get_type(Handle); public float Width => SkiaApi.sk_rrect_get_width(Handle); public float Height => SkiaApi.sk_rrect_get_height(Handle); public bool IsValid => SkiaApi.sk_rrect_is_valid(Handle); public bool AllCornersCircular => CheckAllCornersCircular(0.00024414062f); internal SKRoundRect(IntPtr handle, bool owns) : base(handle, owns) { } public SKRoundRect() : this(SkiaApi.sk_rrect_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKRoundRect instance."); } SetEmpty(); } public SKRoundRect(SKRect rect) : this(SkiaApi.sk_rrect_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKRoundRect instance."); } SetRect(rect); } public SKRoundRect(SKRect rect, float radius) : this(rect, radius, radius) { } public SKRoundRect(SKRect rect, float xRadius, float yRadius) : this(SkiaApi.sk_rrect_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKRoundRect instance."); } SetRect(rect, xRadius, yRadius); } public SKRoundRect(SKRoundRect rrect) : this(SkiaApi.sk_rrect_new_copy(rrect.Handle), owns: true) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_rrect_delete(Handle); } public bool CheckAllCornersCircular(float tolerance) { SKPoint radii = GetRadii(SKRoundRectCorner.UpperLeft); SKPoint radii2 = GetRadii(SKRoundRectCorner.UpperRight); SKPoint radii3 = GetRadii(SKRoundRectCorner.LowerRight); SKPoint radii4 = GetRadii(SKRoundRectCorner.LowerLeft); if (Utils.NearlyEqual(radii.X, radii.Y, tolerance) && Utils.NearlyEqual(radii2.X, radii2.Y, tolerance) && Utils.NearlyEqual(radii3.X, radii3.Y, tolerance)) { return Utils.NearlyEqual(radii4.X, radii4.Y, tolerance); } return false; } public void SetEmpty() { SkiaApi.sk_rrect_set_empty(Handle); } public unsafe void SetRect(SKRect rect) { SkiaApi.sk_rrect_set_rect(Handle, &rect); } public unsafe void SetRect(SKRect rect, float xRadius, float yRadius) { SkiaApi.sk_rrect_set_rect_xy(Handle, &rect, xRadius, yRadius); } public unsafe void SetOval(SKRect rect) { SkiaApi.sk_rrect_set_oval(Handle, &rect); } public unsafe void SetNinePatch(SKRect rect, float leftRadius, float topRadius, float rightRadius, float bottomRadius) { SkiaApi.sk_rrect_set_nine_patch(Handle, &rect, leftRadius, topRadius, rightRadius, bottomRadius); } public unsafe void SetRectRadii(SKRect rect, SKPoint[] radii) { if (radii == null) { throw new ArgumentNullException("radii"); } if (radii.Length != 4) { throw new ArgumentException("Radii must have a length of 4.", "radii"); } fixed (SKPoint* radii2 = radii) { SkiaApi.sk_rrect_set_rect_radii(Handle, &rect, radii2); } } public unsafe bool Contains(SKRect rect) { return SkiaApi.sk_rrect_contains(Handle, &rect); } public unsafe SKPoint GetRadii(SKRoundRectCorner corner) { SKPoint result = default(SKPoint); SkiaApi.sk_rrect_get_radii(Handle, corner, &result); return result; } public void Deflate(SKSize size) { Deflate(size.Width, size.Height); } public void Deflate(float dx, float dy) { SkiaApi.sk_rrect_inset(Handle, dx, dy); } public void Inflate(SKSize size) { Inflate(size.Width, size.Height); } public void Inflate(float dx, float dy) { SkiaApi.sk_rrect_outset(Handle, dx, dy); } public void Offset(SKPoint pos) { Offset(pos.X, pos.Y); } public void Offset(float dx, float dy) { SkiaApi.sk_rrect_offset(Handle, dx, dy); } public unsafe bool TryTransform(SKMatrix matrix, out SKRoundRect transformed) { IntPtr intPtr = SkiaApi.sk_rrect_new(); if (SkiaApi.sk_rrect_transform(Handle, &matrix, intPtr)) { transformed = new SKRoundRect(intPtr, owns: true); return true; } SkiaApi.sk_rrect_delete(intPtr); transformed = null; return false; } public SKRoundRect Transform(SKMatrix matrix) { if (TryTransform(matrix, out var transformed)) { return transformed; } return null; } } public class SKRunBuffer { internal readonly SKRunBufferInternal internalBuffer; public int Size { get; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public int TextSize { get; } internal SKRunBuffer(SKRunBufferInternal buffer, int size) { internalBuffer = buffer; Size = size; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] internal SKRunBuffer(SKRunBufferInternal buffer, int size, int textSize) { internalBuffer = buffer; Size = size; TextSize = textSize; } public unsafe Span GetGlyphSpan() { return new Span(internalBuffer.glyphs, (internalBuffer.glyphs != null) ? Size : 0); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public unsafe Span GetTextSpan() { return new Span(internalBuffer.utf8text, (internalBuffer.utf8text != null) ? TextSize : 0); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public unsafe Span GetClusterSpan() { return new Span(internalBuffer.clusters, (internalBuffer.clusters != null) ? Size : 0); } public void SetGlyphs(ReadOnlySpan glyphs) { glyphs.CopyTo(GetGlyphSpan()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public void SetText(ReadOnlySpan text) { text.CopyTo(GetTextSpan()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public void SetClusters(ReadOnlySpan clusters) { clusters.CopyTo(GetClusterSpan()); } } public sealed class SKHorizontalRunBuffer : SKRunBuffer { internal SKHorizontalRunBuffer(SKRunBufferInternal buffer, int count) : base(buffer, count) { } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] internal SKHorizontalRunBuffer(SKRunBufferInternal buffer, int count, int textSize) : base(buffer, count, textSize) { } public unsafe Span GetPositionSpan() { return new Span(internalBuffer.pos, (internalBuffer.pos != null) ? base.Size : 0); } public void SetPositions(ReadOnlySpan positions) { positions.CopyTo(GetPositionSpan()); } } public sealed class SKPositionedRunBuffer : SKRunBuffer { internal SKPositionedRunBuffer(SKRunBufferInternal buffer, int count) : base(buffer, count) { } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] internal SKPositionedRunBuffer(SKRunBufferInternal buffer, int count, int textSize) : base(buffer, count, textSize) { } public unsafe Span GetPositionSpan() { return new Span(internalBuffer.pos, (internalBuffer.pos != null) ? base.Size : 0); } public void SetPositions(ReadOnlySpan positions) { positions.CopyTo(GetPositionSpan()); } } public sealed class SKRotationScaleRunBuffer : SKRunBuffer { internal SKRotationScaleRunBuffer(SKRunBufferInternal buffer, int count) : base(buffer, count) { } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] internal SKRotationScaleRunBuffer(SKRunBufferInternal buffer, int count, int textSize) : base(buffer, count, textSize) { } public unsafe Span GetRotationScaleSpan() { return new Span(internalBuffer.pos, base.Size); } public void SetRotationScale(ReadOnlySpan positions) { positions.CopyTo(GetRotationScaleSpan()); } } public class SKRuntimeEffect : SKObject, ISKReferenceCounted { private string[] children; private string[] uniforms; public int UniformSize => (int)SkiaApi.sk_runtimeeffect_get_uniform_size(Handle); public IReadOnlyList Children => children ?? (children = GetChildrenNames().ToArray()); public IReadOnlyList Uniforms => uniforms ?? (uniforms = GetUniformNames().ToArray()); internal SKRuntimeEffect(IntPtr handle, bool owns) : base(handle, owns) { } public static SKRuntimeEffect Create(string sksl, out string errors) { using SKString sKString = new SKString(sksl); using SKString sKString2 = new SKString(); SKRuntimeEffect result = GetObject(SkiaApi.sk_runtimeeffect_make(sKString.Handle, sKString2.Handle)); errors = sKString2?.ToString(); string obj = errors; if (obj != null && obj.Length == 0) { errors = null; } return result; } private IEnumerable GetChildrenNames() { int count = (int)SkiaApi.sk_runtimeeffect_get_children_count(Handle); using SKString str = new SKString(); for (int i = 0; i < count; i++) { SkiaApi.sk_runtimeeffect_get_child_name(Handle, i, str.Handle); yield return str.ToString(); } } private IEnumerable GetUniformNames() { int count = (int)SkiaApi.sk_runtimeeffect_get_uniforms_count(Handle); using SKString str = new SKString(); for (int i = 0; i < count; i++) { SkiaApi.sk_runtimeeffect_get_uniform_name(Handle, i, str.Handle); yield return str.ToString(); } } public unsafe SKShader ToShader(bool isOpaque) { return ToShader(isOpaque, null, null, null); } public unsafe SKShader ToShader(bool isOpaque, SKRuntimeEffectUniforms uniforms) { return ToShader(isOpaque, uniforms.ToData(), null, null); } public unsafe SKShader ToShader(bool isOpaque, SKRuntimeEffectUniforms uniforms, SKRuntimeEffectChildren children) { return ToShader(isOpaque, uniforms.ToData(), children.ToArray(), null); } public unsafe SKShader ToShader(bool isOpaque, SKRuntimeEffectUniforms uniforms, SKRuntimeEffectChildren children, SKMatrix localMatrix) { return ToShader(isOpaque, uniforms.ToData(), children.ToArray(), &localMatrix); } private unsafe SKShader ToShader(bool isOpaque, SKData uniforms, SKShader[] children, SKMatrix* localMatrix) { IntPtr intPtr = uniforms?.Handle ?? IntPtr.Zero; Utils.RentedArray rentedArray = Utils.RentHandlesArray(children, nullIfEmpty: true); try { fixed (IntPtr* ptr = rentedArray) { return SKShader.GetObject(SkiaApi.sk_runtimeeffect_make_shader(Handle, intPtr, ptr, (IntPtr)rentedArray.Length, localMatrix, isOpaque)); } } finally { rentedArray.Dispose(); } } public SKColorFilter ToColorFilter() { return ToColorFilter((SKData)null, (SKShader[])null); } public SKColorFilter ToColorFilter(SKRuntimeEffectUniforms uniforms) { return ToColorFilter(uniforms.ToData(), null); } private SKColorFilter ToColorFilter(SKData uniforms) { return ToColorFilter(uniforms, null); } public SKColorFilter ToColorFilter(SKRuntimeEffectUniforms uniforms, SKRuntimeEffectChildren children) { return ToColorFilter(uniforms.ToData(), children.ToArray()); } private unsafe SKColorFilter ToColorFilter(SKData uniforms, SKShader[] children) { IntPtr intPtr = uniforms?.Handle ?? IntPtr.Zero; Utils.RentedArray rentedArray = Utils.RentHandlesArray(children, nullIfEmpty: true); try { fixed (IntPtr* ptr = rentedArray) { return SKColorFilter.GetObject(SkiaApi.sk_runtimeeffect_make_color_filter(Handle, intPtr, ptr, (IntPtr)rentedArray.Length)); } } finally { rentedArray.Dispose(); } } internal static SKRuntimeEffect GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKRuntimeEffect(h, o)); } } public class SKRuntimeEffectUniforms : IEnumerable, IEnumerable { internal struct Variable { public int Index { get; set; } public string Name { get; set; } public int Offset { get; set; } public int Size { get; set; } } private readonly string[] names; private readonly Dictionary uniforms; private SKData data; public IReadOnlyList Names => names; internal IReadOnlyList Variables => uniforms.Values.OrderBy((Variable v) => v.Index).ToArray(); public int Count => names.Length; public SKRuntimeEffectUniform this[string name] { set { Add(name, value); } } public SKRuntimeEffectUniforms(SKRuntimeEffect effect) { if (effect == null) { throw new ArgumentNullException("effect"); } names = effect.Uniforms.ToArray(); uniforms = new Dictionary(); int uniformSize = effect.UniformSize; data = ((uniformSize > 0) ? SKData.Create(effect.UniformSize) : SKData.Empty); for (int i = 0; i < names.Length; i++) { string text = names[i]; IntPtr variable = SkiaApi.sk_runtimeeffect_get_uniform_from_index(effect.Handle, i); uniforms[text] = new Variable { Index = i, Name = text, Offset = (int)SkiaApi.sk_runtimeeffect_uniform_get_offset(variable), Size = (int)SkiaApi.sk_runtimeeffect_uniform_get_size_in_bytes(variable) }; } } public void Reset() { if (data.Size != 0L) { data = SKData.Create(data.Size); } } public bool Contains(string name) { return Array.IndexOf(names, name) != -1; } public void Add(string name, SKRuntimeEffectUniform value) { int num = Array.IndexOf(names, name); if (num == -1) { throw new ArgumentOutOfRangeException(name, "Variable was not found for name: '" + name + "'."); } Variable variable = uniforms[name]; Span span = data.Span.Slice(variable.Offset, variable.Size); if (value.IsEmpty) { span.Fill(0); return; } if (value.Size != variable.Size) { throw new ArgumentException($"Value size of {value.Size} does not match uniform size of {variable.Size}.", "value"); } value.WriteTo(span); } public SKData ToData() { if (data.Size == 0L) { return SKData.Empty; } return SKData.CreateCopy(data.Data, data.Size); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { return ((IEnumerable)names).GetEnumerator(); } } public class SKRuntimeEffectChildren : IEnumerable, IEnumerable { private readonly string[] names; private readonly SKShader[] children; public IReadOnlyList Names => names; public int Count => names.Length; public SKShader this[string name] { set { Add(name, value); } } public SKRuntimeEffectChildren(SKRuntimeEffect effect) { if (effect == null) { throw new ArgumentNullException("effect"); } names = effect.Children.ToArray(); children = new SKShader[names.Length]; } public void Reset() { Array.Clear(children, 0, children.Length); } public bool Contains(string name) { return Array.IndexOf(names, name) != -1; } public void Add(string name, SKShader value) { int num = Array.IndexOf(names, name); if (num == -1) { throw new ArgumentOutOfRangeException(name, "Variable was not found for name: '" + name + "'."); } children[num] = value; } public SKShader[] ToArray() { return children.ToArray(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { return ((IEnumerable)names).GetEnumerator(); } } public readonly ref struct SKRuntimeEffectUniform { private enum DataType { Empty, Float, FloatArray } private readonly DataType type; private readonly int size; private readonly float floatValue; private readonly ReadOnlySpan floatArray; public static SKRuntimeEffectUniform Empty => default(SKRuntimeEffectUniform); public bool IsEmpty => type == DataType.Empty; public int Size => size; private SKRuntimeEffectUniform(DataType type, int size, float floatValue = 0f, ReadOnlySpan floatArray = default(ReadOnlySpan)) { this.type = type; this.size = size; this.floatValue = floatValue; this.floatArray = floatArray; } public static implicit operator SKRuntimeEffectUniform(float value) { return new SKRuntimeEffectUniform(DataType.Float, 4, value); } public static implicit operator SKRuntimeEffectUniform(float[] value) { return (ReadOnlySpan)value; } public static implicit operator SKRuntimeEffectUniform(Span value) { return (ReadOnlySpan)value; } public static implicit operator SKRuntimeEffectUniform(ReadOnlySpan value) { return new SKRuntimeEffectUniform(DataType.FloatArray, 4 * value.Length, 0f, value); } public static implicit operator SKRuntimeEffectUniform(float[][] value) { List list = new List(); foreach (float[] collection in value) { list.AddRange(collection); } return list.ToArray(); } public static implicit operator SKRuntimeEffectUniform(SKMatrix value) { return value.Values; } public unsafe void WriteTo(Span data) { switch (type) { case DataType.Float: fixed (float* ptr2 = &floatValue) { void* pointer2 = ptr2; new ReadOnlySpan(pointer2, size).CopyTo(data); } break; case DataType.FloatArray: fixed (float* ptr = floatArray) { void* pointer = ptr; new ReadOnlySpan(pointer, size).CopyTo(data); } break; default: data.Fill(0); break; } } } public class SKShader : SKObject, ISKReferenceCounted { internal SKShader(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public SKShader WithColorFilter(SKColorFilter filter) { if (filter == null) { throw new ArgumentNullException("filter"); } return GetObject(SkiaApi.sk_shader_with_color_filter(Handle, filter.Handle)); } public unsafe SKShader WithLocalMatrix(SKMatrix localMatrix) { return GetObject(SkiaApi.sk_shader_with_local_matrix(Handle, &localMatrix)); } public static SKShader CreateEmpty() { return GetObject(SkiaApi.sk_shader_new_empty()); } public static SKShader CreateColor(SKColor color) { return GetObject(SkiaApi.sk_shader_new_color((uint)color)); } public unsafe static SKShader CreateColor(SKColorF color, SKColorSpace colorspace) { if (colorspace == null) { throw new ArgumentNullException("colorspace"); } return GetObject(SkiaApi.sk_shader_new_color4f(&color, colorspace.Handle)); } public static SKShader CreateBitmap(SKBitmap src) { return CreateBitmap(src, SKShaderTileMode.Clamp, SKShaderTileMode.Clamp); } public static SKShader CreateBitmap(SKBitmap src, SKShaderTileMode tmx, SKShaderTileMode tmy) { if (src == null) { throw new ArgumentNullException("src"); } return src.ToShader(tmx, tmy); } public static SKShader CreateBitmap(SKBitmap src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix) { if (src == null) { throw new ArgumentNullException("src"); } return src.ToShader(tmx, tmy, localMatrix); } public static SKShader CreateImage(SKImage src) { return CreateImage(src, SKShaderTileMode.Clamp, SKShaderTileMode.Clamp); } public static SKShader CreateImage(SKImage src, SKShaderTileMode tmx, SKShaderTileMode tmy) { if (src == null) { throw new ArgumentNullException("src"); } return src.ToShader(tmx, tmy); } public static SKShader CreateImage(SKImage src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix) { if (src == null) { throw new ArgumentNullException("src"); } return src.ToShader(tmx, tmy, localMatrix); } public static SKShader CreatePicture(SKPicture src) { return CreatePicture(src, SKShaderTileMode.Clamp, SKShaderTileMode.Clamp); } public static SKShader CreatePicture(SKPicture src, SKShaderTileMode tmx, SKShaderTileMode tmy) { if (src == null) { throw new ArgumentNullException("src"); } return src.ToShader(tmx, tmy); } public static SKShader CreatePicture(SKPicture src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKRect tile) { if (src == null) { throw new ArgumentNullException("src"); } return src.ToShader(tmx, tmy, tile); } public static SKShader CreatePicture(SKPicture src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix, SKRect tile) { if (src == null) { throw new ArgumentNullException("src"); } return src.ToShader(tmx, tmy, localMatrix, tile); } public static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColor[] colors, SKShaderTileMode mode) { return CreateLinearGradient(start, end, colors, null, mode); } public unsafe static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColor[] colors, float[] colorPos, SKShaderTileMode mode) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } SKPoint* points = stackalloc SKPoint[2] { start, end }; fixed (SKColor* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_linear_gradient(points, (uint*)colors2, colorPos2, colors.Length, mode, null)); } } } public unsafe static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColor[] colors, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } SKPoint* points = stackalloc SKPoint[2] { start, end }; fixed (SKColor* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_linear_gradient(points, (uint*)colors2, colorPos2, colors.Length, mode, &localMatrix)); } } } public static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColorF[] colors, SKColorSpace colorspace, SKShaderTileMode mode) { return CreateLinearGradient(start, end, colors, colorspace, null, mode); } public unsafe static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKShaderTileMode mode) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } SKPoint* points = stackalloc SKPoint[2] { start, end }; fixed (SKColorF* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_linear_gradient_color4f(points, colors2, colorspace?.Handle ?? IntPtr.Zero, colorPos2, colors.Length, mode, null)); } } } public unsafe static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } SKPoint* points = stackalloc SKPoint[2] { start, end }; fixed (SKColorF* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_linear_gradient_color4f(points, colors2, colorspace?.Handle ?? IntPtr.Zero, colorPos2, colors.Length, mode, &localMatrix)); } } } public static SKShader CreateRadialGradient(SKPoint center, float radius, SKColor[] colors, SKShaderTileMode mode) { return CreateRadialGradient(center, radius, colors, null, mode); } public unsafe static SKShader CreateRadialGradient(SKPoint center, float radius, SKColor[] colors, float[] colorPos, SKShaderTileMode mode) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColor* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_radial_gradient(¢er, radius, (uint*)colors2, colorPos2, colors.Length, mode, null)); } } } public unsafe static SKShader CreateRadialGradient(SKPoint center, float radius, SKColor[] colors, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColor* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_radial_gradient(¢er, radius, (uint*)colors2, colorPos2, colors.Length, mode, &localMatrix)); } } } public static SKShader CreateRadialGradient(SKPoint center, float radius, SKColorF[] colors, SKColorSpace colorspace, SKShaderTileMode mode) { return CreateRadialGradient(center, radius, colors, colorspace, null, mode); } public unsafe static SKShader CreateRadialGradient(SKPoint center, float radius, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKShaderTileMode mode) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColorF* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_radial_gradient_color4f(¢er, radius, colors2, colorspace?.Handle ?? IntPtr.Zero, colorPos2, colors.Length, mode, null)); } } } public unsafe static SKShader CreateRadialGradient(SKPoint center, float radius, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColorF* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_radial_gradient_color4f(¢er, radius, colors2, colorspace?.Handle ?? IntPtr.Zero, colorPos2, colors.Length, mode, &localMatrix)); } } } public static SKShader CreateSweepGradient(SKPoint center, SKColor[] colors) { return CreateSweepGradient(center, colors, null, SKShaderTileMode.Clamp, 0f, 360f); } public static SKShader CreateSweepGradient(SKPoint center, SKColor[] colors, float[] colorPos) { return CreateSweepGradient(center, colors, colorPos, SKShaderTileMode.Clamp, 0f, 360f); } public static SKShader CreateSweepGradient(SKPoint center, SKColor[] colors, float[] colorPos, SKMatrix localMatrix) { return CreateSweepGradient(center, colors, colorPos, SKShaderTileMode.Clamp, 0f, 360f, localMatrix); } public static SKShader CreateSweepGradient(SKPoint center, SKColor[] colors, SKShaderTileMode tileMode, float startAngle, float endAngle) { return CreateSweepGradient(center, colors, null, tileMode, startAngle, endAngle); } public unsafe static SKShader CreateSweepGradient(SKPoint center, SKColor[] colors, float[] colorPos, SKShaderTileMode tileMode, float startAngle, float endAngle) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColor* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_sweep_gradient(¢er, (uint*)colors2, colorPos2, colors.Length, tileMode, startAngle, endAngle, null)); } } } public unsafe static SKShader CreateSweepGradient(SKPoint center, SKColor[] colors, float[] colorPos, SKShaderTileMode tileMode, float startAngle, float endAngle, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColor* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_sweep_gradient(¢er, (uint*)colors2, colorPos2, colors.Length, tileMode, startAngle, endAngle, &localMatrix)); } } } public static SKShader CreateSweepGradient(SKPoint center, SKColorF[] colors, SKColorSpace colorspace) { return CreateSweepGradient(center, colors, colorspace, null, SKShaderTileMode.Clamp, 0f, 360f); } public static SKShader CreateSweepGradient(SKPoint center, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos) { return CreateSweepGradient(center, colors, colorspace, colorPos, SKShaderTileMode.Clamp, 0f, 360f); } public static SKShader CreateSweepGradient(SKPoint center, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKMatrix localMatrix) { return CreateSweepGradient(center, colors, colorspace, colorPos, SKShaderTileMode.Clamp, 0f, 360f, localMatrix); } public static SKShader CreateSweepGradient(SKPoint center, SKColorF[] colors, SKColorSpace colorspace, SKShaderTileMode tileMode, float startAngle, float endAngle) { return CreateSweepGradient(center, colors, colorspace, null, tileMode, startAngle, endAngle); } public unsafe static SKShader CreateSweepGradient(SKPoint center, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKShaderTileMode tileMode, float startAngle, float endAngle) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColorF* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_sweep_gradient_color4f(¢er, colors2, colorspace?.Handle ?? IntPtr.Zero, colorPos2, colors.Length, tileMode, startAngle, endAngle, null)); } } } public unsafe static SKShader CreateSweepGradient(SKPoint center, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKShaderTileMode tileMode, float startAngle, float endAngle, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColorF* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_sweep_gradient_color4f(¢er, colors2, colorspace?.Handle ?? IntPtr.Zero, colorPos2, colors.Length, tileMode, startAngle, endAngle, &localMatrix)); } } } public static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColor[] colors, SKShaderTileMode mode) { return CreateTwoPointConicalGradient(start, startRadius, end, endRadius, colors, null, mode); } public unsafe static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColor[] colors, float[] colorPos, SKShaderTileMode mode) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColor* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_two_point_conical_gradient(&start, startRadius, &end, endRadius, (uint*)colors2, colorPos2, colors.Length, mode, null)); } } } public unsafe static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColor[] colors, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColor* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_two_point_conical_gradient(&start, startRadius, &end, endRadius, (uint*)colors2, colorPos2, colors.Length, mode, &localMatrix)); } } } public static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColorF[] colors, SKColorSpace colorspace, SKShaderTileMode mode) { return CreateTwoPointConicalGradient(start, startRadius, end, endRadius, colors, colorspace, null, mode); } public unsafe static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKShaderTileMode mode) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColorF* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_two_point_conical_gradient_color4f(&start, startRadius, &end, endRadius, colors2, colorspace?.Handle ?? IntPtr.Zero, colorPos2, colors.Length, mode, null)); } } } public unsafe static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColorF[] colors, SKColorSpace colorspace, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException("colors"); } if (colorPos != null && colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } fixed (SKColorF* colors2 = colors) { fixed (float* colorPos2 = colorPos) { return GetObject(SkiaApi.sk_shader_new_two_point_conical_gradient_color4f(&start, startRadius, &end, endRadius, colors2, colorspace?.Handle ?? IntPtr.Zero, colorPos2, colors.Length, mode, &localMatrix)); } } } public unsafe static SKShader CreatePerlinNoiseFractalNoise(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed) { return GetObject(SkiaApi.sk_shader_new_perlin_noise_fractal_noise(baseFrequencyX, baseFrequencyY, numOctaves, seed, null)); } public static SKShader CreatePerlinNoiseFractalNoise(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKPointI tileSize) { return CreatePerlinNoiseFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed, (SKSizeI)tileSize); } public unsafe static SKShader CreatePerlinNoiseFractalNoise(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKSizeI tileSize) { return GetObject(SkiaApi.sk_shader_new_perlin_noise_fractal_noise(baseFrequencyX, baseFrequencyY, numOctaves, seed, &tileSize)); } public static SKShader CreatePerlinNoiseImprovedNoise(float baseFrequencyX, float baseFrequencyY, int numOctaves, float z) { return GetObject(SkiaApi.sk_shader_new_perlin_noise_improved_noise(baseFrequencyX, baseFrequencyY, numOctaves, z)); } public unsafe static SKShader CreatePerlinNoiseTurbulence(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed) { return GetObject(SkiaApi.sk_shader_new_perlin_noise_turbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed, null)); } public static SKShader CreatePerlinNoiseTurbulence(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKPointI tileSize) { return CreatePerlinNoiseTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed, (SKSizeI)tileSize); } public unsafe static SKShader CreatePerlinNoiseTurbulence(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKSizeI tileSize) { return GetObject(SkiaApi.sk_shader_new_perlin_noise_turbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed, &tileSize)); } public static SKShader CreateCompose(SKShader shaderA, SKShader shaderB) { return CreateCompose(shaderA, shaderB, SKBlendMode.SrcOver); } public static SKShader CreateCompose(SKShader shaderA, SKShader shaderB, SKBlendMode mode) { if (shaderA == null) { throw new ArgumentNullException("shaderA"); } if (shaderB == null) { throw new ArgumentNullException("shaderB"); } return GetObject(SkiaApi.sk_shader_new_blend(mode, shaderA.Handle, shaderB.Handle)); } public static SKShader CreateLerp(float weight, SKShader dst, SKShader src) { if (dst == null) { throw new ArgumentNullException("dst"); } if (src == null) { throw new ArgumentNullException("src"); } return GetObject(SkiaApi.sk_shader_new_lerp(weight, dst.Handle, src.Handle)); } public static SKShader CreateColorFilter(SKShader shader, SKColorFilter filter) { if (shader == null) { throw new ArgumentNullException("shader"); } if (filter == null) { throw new ArgumentNullException("filter"); } return shader.WithColorFilter(filter); } public static SKShader CreateLocalMatrix(SKShader shader, SKMatrix localMatrix) { if (shader == null) { throw new ArgumentNullException("shader"); } return shader.WithLocalMatrix(localMatrix); } internal static SKShader GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKShader(h, o)); } } public abstract class SKStream : SKObject { public bool IsAtEnd => SkiaApi.sk_stream_is_at_end(Handle); public bool HasPosition => SkiaApi.sk_stream_has_position(Handle); public int Position { get { return (int)SkiaApi.sk_stream_get_position(Handle); } set { Seek(value); } } public bool HasLength => SkiaApi.sk_stream_has_length(Handle); public int Length => (int)SkiaApi.sk_stream_get_length(Handle); internal SKStream(IntPtr handle, bool owns) : base(handle, owns) { } public sbyte ReadSByte() { if (ReadSByte(out var buffer)) { return buffer; } return 0; } public short ReadInt16() { if (ReadInt16(out var buffer)) { return buffer; } return 0; } public int ReadInt32() { if (ReadInt32(out var buffer)) { return buffer; } return 0; } public byte ReadByte() { if (ReadByte(out var buffer)) { return buffer; } return 0; } public ushort ReadUInt16() { if (ReadUInt16(out var buffer)) { return buffer; } return 0; } public uint ReadUInt32() { if (ReadUInt32(out var buffer)) { return buffer; } return 0u; } public bool ReadBool() { if (ReadBool(out var buffer)) { return buffer; } return false; } public unsafe bool ReadSByte(out sbyte buffer) { fixed (sbyte* buffer2 = &buffer) { return SkiaApi.sk_stream_read_s8(Handle, buffer2); } } public unsafe bool ReadInt16(out short buffer) { fixed (short* buffer2 = &buffer) { return SkiaApi.sk_stream_read_s16(Handle, buffer2); } } public unsafe bool ReadInt32(out int buffer) { fixed (int* buffer2 = &buffer) { return SkiaApi.sk_stream_read_s32(Handle, buffer2); } } public unsafe bool ReadByte(out byte buffer) { fixed (byte* buffer2 = &buffer) { return SkiaApi.sk_stream_read_u8(Handle, buffer2); } } public unsafe bool ReadUInt16(out ushort buffer) { fixed (ushort* buffer2 = &buffer) { return SkiaApi.sk_stream_read_u16(Handle, buffer2); } } public unsafe bool ReadUInt32(out uint buffer) { fixed (uint* buffer2 = &buffer) { return SkiaApi.sk_stream_read_u32(Handle, buffer2); } } public unsafe bool ReadBool(out bool buffer) { byte b = default(byte); bool result = SkiaApi.sk_stream_read_bool(Handle, &b); buffer = b > 0; return result; } public unsafe int Read(byte[] buffer, int size) { fixed (byte* ptr = buffer) { return Read((IntPtr)ptr, size); } } public unsafe int Read(IntPtr buffer, int size) { return (int)SkiaApi.sk_stream_read(Handle, (void*)buffer, (IntPtr)size); } public unsafe int Peek(IntPtr buffer, int size) { return (int)SkiaApi.sk_stream_peek(Handle, (void*)buffer, (IntPtr)size); } public int Skip(int size) { return (int)SkiaApi.sk_stream_skip(Handle, (IntPtr)size); } public bool Rewind() { return SkiaApi.sk_stream_rewind(Handle); } public bool Seek(int position) { return SkiaApi.sk_stream_seek(Handle, (IntPtr)position); } public bool Move(long offset) { return Move((int)offset); } public bool Move(int offset) { return SkiaApi.sk_stream_move(Handle, offset); } public unsafe IntPtr GetMemoryBase() { return (IntPtr)SkiaApi.sk_stream_get_memory_base(Handle); } internal SKStream Fork() { return GetObject(SkiaApi.sk_stream_fork(Handle)); } internal SKStream Duplicate() { return GetObject(SkiaApi.sk_stream_duplicate(Handle)); } internal static SKStream GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (Func)((IntPtr h, bool o) => new SKStreamImplementation(h, o))); } } internal class SKStreamImplementation : SKStream { internal SKStreamImplementation(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_stream_destroy(Handle); } } public abstract class SKStreamRewindable : SKStream { internal SKStreamRewindable(IntPtr handle, bool owns) : base(handle, owns) { } } public abstract class SKStreamSeekable : SKStreamRewindable { internal SKStreamSeekable(IntPtr handle, bool owns) : base(handle, owns) { } } public abstract class SKStreamAsset : SKStreamSeekable { internal SKStreamAsset(IntPtr handle, bool owns) : base(handle, owns) { } internal new static SKStreamAsset GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (Func)((IntPtr h, bool o) => new SKStreamAssetImplementation(h, o))); } } internal class SKStreamAssetImplementation : SKStreamAsset { internal SKStreamAssetImplementation(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_stream_asset_destroy(Handle); } } public abstract class SKStreamMemory : SKStreamAsset { internal SKStreamMemory(IntPtr handle, bool owns) : base(handle, owns) { } } public class SKFileStream : SKStreamAsset { public bool IsValid => SkiaApi.sk_filestream_is_valid(Handle); internal SKFileStream(IntPtr handle, bool owns) : base(handle, owns) { } public SKFileStream(string path) : base(CreateNew(path), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKFileStream instance."); } } private unsafe static IntPtr CreateNew(string path) { fixed (byte* encodedText = StringUtilities.GetEncodedText(path, SKTextEncoding.Utf8, addNull: true)) { return SkiaApi.sk_filestream_new(encodedText); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_filestream_destroy(Handle); } public static bool IsPathSupported(string path) { return true; } public static SKStreamAsset OpenStream(string path) { SKFileStream sKFileStream = new SKFileStream(path); if (!sKFileStream.IsValid) { sKFileStream.Dispose(); sKFileStream = null; } return sKFileStream; } } public class SKMemoryStream : SKStreamMemory { internal SKMemoryStream(IntPtr handle, bool owns) : base(handle, owns) { } public SKMemoryStream() : this(SkiaApi.sk_memorystream_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKMemoryStream instance."); } } public SKMemoryStream(ulong length) : this(SkiaApi.sk_memorystream_new_with_length((IntPtr)(long)length), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKMemoryStream instance."); } } internal unsafe SKMemoryStream(IntPtr data, IntPtr length, bool copyData = false) : this(SkiaApi.sk_memorystream_new_with_data((void*)data, length, copyData), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKMemoryStream instance."); } } public SKMemoryStream(SKData data) : this(SkiaApi.sk_memorystream_new_with_skdata(data.Handle), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKMemoryStream instance."); } } public SKMemoryStream(byte[] data) : this() { SetMemory(data); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_memorystream_destroy(Handle); } internal unsafe void SetMemory(IntPtr data, IntPtr length, bool copyData = false) { SkiaApi.sk_memorystream_set_memory(Handle, (void*)data, length, copyData); } internal unsafe void SetMemory(byte[] data, IntPtr length, bool copyData = false) { fixed (byte* data2 = data) { SkiaApi.sk_memorystream_set_memory(Handle, data2, length, copyData); } } public void SetMemory(byte[] data) { SetMemory(data, (IntPtr)data.Length, copyData: true); } } public abstract class SKWStream : SKObject { public virtual int BytesWritten => (int)SkiaApi.sk_wstream_bytes_written(Handle); internal SKWStream(IntPtr handle, bool owns) : base(handle, owns) { } public unsafe virtual bool Write(byte[] buffer, int size) { fixed (byte* buffer2 = buffer) { return SkiaApi.sk_wstream_write(Handle, buffer2, (IntPtr)size); } } public bool NewLine() { return SkiaApi.sk_wstream_newline(Handle); } public virtual void Flush() { SkiaApi.sk_wstream_flush(Handle); } public bool Write8(byte value) { return SkiaApi.sk_wstream_write_8(Handle, value); } public bool Write16(ushort value) { return SkiaApi.sk_wstream_write_16(Handle, value); } public bool Write32(uint value) { return SkiaApi.sk_wstream_write_32(Handle, value); } public bool WriteText(string value) { return SkiaApi.sk_wstream_write_text(Handle, value); } public bool WriteDecimalAsTest(int value) { return SkiaApi.sk_wstream_write_dec_as_text(Handle, value); } public bool WriteBigDecimalAsText(long value, int digits) { return SkiaApi.sk_wstream_write_bigdec_as_text(Handle, value, digits); } public bool WriteHexAsText(uint value, int digits) { return SkiaApi.sk_wstream_write_hex_as_text(Handle, value, digits); } public bool WriteScalarAsText(float value) { return SkiaApi.sk_wstream_write_scalar_as_text(Handle, value); } public bool WriteBool(bool value) { return SkiaApi.sk_wstream_write_bool(Handle, value); } public bool WriteScalar(float value) { return SkiaApi.sk_wstream_write_scalar(Handle, value); } public bool WritePackedUInt32(uint value) { return SkiaApi.sk_wstream_write_packed_uint(Handle, (IntPtr)value); } public bool WriteStream(SKStream input, int length) { if (input == null) { throw new ArgumentNullException("input"); } return SkiaApi.sk_wstream_write_stream(Handle, input.Handle, (IntPtr)length); } public static int GetSizeOfPackedUInt32(uint value) { return SkiaApi.sk_wstream_get_size_of_packed_uint((IntPtr)value); } } public class SKFileWStream : SKWStream { public bool IsValid => SkiaApi.sk_filewstream_is_valid(Handle); internal SKFileWStream(IntPtr handle, bool owns) : base(handle, owns) { } public SKFileWStream(string path) : base(CreateNew(path), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKFileWStream instance."); } } private unsafe static IntPtr CreateNew(string path) { fixed (byte* encodedText = StringUtilities.GetEncodedText(path, SKTextEncoding.Utf8, addNull: true)) { return SkiaApi.sk_filewstream_new(encodedText); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_filewstream_destroy(Handle); } public static bool IsPathSupported(string path) { return true; } public static SKWStream OpenStream(string path) { SKFileWStream sKFileWStream = new SKFileWStream(path); if (!sKFileWStream.IsValid) { sKFileWStream.Dispose(); sKFileWStream = null; } return sKFileWStream; } } public class SKDynamicMemoryWStream : SKWStream { internal SKDynamicMemoryWStream(IntPtr handle, bool owns) : base(handle, owns) { } public SKDynamicMemoryWStream() : base(SkiaApi.sk_dynamicmemorywstream_new(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKDynamicMemoryWStream instance."); } } public SKData CopyToData() { SKData sKData = SKData.Create(BytesWritten); CopyTo(sKData.Data); return sKData; } public SKStreamAsset DetachAsStream() { return SKStreamAsset.GetObject(SkiaApi.sk_dynamicmemorywstream_detach_as_stream(Handle)); } public SKData DetachAsData() { return SKData.GetObject(SkiaApi.sk_dynamicmemorywstream_detach_as_data(Handle)); } public unsafe void CopyTo(IntPtr data) { SkiaApi.sk_dynamicmemorywstream_copy_to(Handle, (void*)data); } public unsafe void CopyTo(Span data) { int bytesWritten = BytesWritten; if (data.Length < bytesWritten) { throw new Exception($"Not enough space to copy. Expected at least {bytesWritten}, but received {data.Length}."); } fixed (byte* ptr = data) { void* data2 = ptr; SkiaApi.sk_dynamicmemorywstream_copy_to(Handle, data2); } } public bool CopyTo(SKWStream dst) { if (dst == null) { throw new ArgumentNullException("dst"); } return SkiaApi.sk_dynamicmemorywstream_write_to_stream(Handle, dst.Handle); } public bool CopyTo(Stream dst) { if (dst == null) { throw new ArgumentNullException("dst"); } using SKManagedWStream dst2 = new SKManagedWStream(dst); return CopyTo(dst2); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_dynamicmemorywstream_destroy(Handle); } } internal class SKString : SKObject, ISKSkipObjectRegistration { internal SKString(IntPtr handle, bool owns) : base(handle, owns) { } public SKString() : base(SkiaApi.sk_string_new_empty(), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKString instance."); } } public SKString(byte[] src, long length) : base(CreateCopy(src, length), owns: true) { if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to copy the SKString instance."); } } private unsafe static IntPtr CreateCopy(byte[] src, long length) { fixed (byte* src2 = src) { return SkiaApi.sk_string_new_with_copy(src2, (IntPtr)length); } } public SKString(byte[] src) : this(src, src.Length) { } public SKString(string str) : this(StringUtilities.GetEncodedText(str, SKTextEncoding.Utf8)) { } public unsafe override string ToString() { void* ptr = SkiaApi.sk_string_get_c_str(Handle); IntPtr intPtr = SkiaApi.sk_string_get_size(Handle); return StringUtilities.GetString((IntPtr)ptr, (int)intPtr, SKTextEncoding.Utf8); } public static explicit operator string(SKString skString) { return skString.ToString(); } internal static SKString Create(string str) { if (str == null) { return null; } return new SKString(str); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_string_destructor(Handle); } internal static SKString GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new SKString(handle, owns: true); } return null; } } public class SKSurface : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration { public SKCanvas Canvas => SKObject.OwnedBy(SKCanvas.GetObject(SkiaApi.sk_surface_get_canvas(Handle), owns: false, unrefExisting: false), this); [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use SurfaceProperties instead.")] public SKSurfaceProps SurfaceProps { get { SKSurfaceProperties surfaceProperties = SurfaceProperties; return new SKSurfaceProps { Flags = surfaceProperties.Flags, PixelGeometry = surfaceProperties.PixelGeometry }; } } public SKSurfaceProperties SurfaceProperties => SKObject.OwnedBy(SKSurfaceProperties.GetObject(SkiaApi.sk_surface_get_props(Handle), owns: false), this); public GRRecordingContext Context => GRRecordingContext.GetObject(SkiaApi.sk_surface_get_recording_context(Handle), owns: false, unrefExisting: false); [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(SKImageInfo) instead.")] public static SKSurface Create(int width, int height, SKColorType colorType, SKAlphaType alphaType) { return Create(new SKImageInfo(width, height, colorType, alphaType)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(SKImageInfo, SKSurfaceProperties) instead.")] public static SKSurface Create(int width, int height, SKColorType colorType, SKAlphaType alphaType, SKSurfaceProps props) { return Create(new SKImageInfo(width, height, colorType, alphaType), props); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(SKImageInfo, IntPtr, int) instead.")] public static SKSurface Create(int width, int height, SKColorType colorType, SKAlphaType alphaType, IntPtr pixels, int rowBytes) { return Create(new SKImageInfo(width, height, colorType, alphaType), pixels, rowBytes); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(SKImageInfo, IntPtr, int, SKSurfaceProperties) instead.")] public static SKSurface Create(int width, int height, SKColorType colorType, SKAlphaType alphaType, IntPtr pixels, int rowBytes, SKSurfaceProps props) { return Create(new SKImageInfo(width, height, colorType, alphaType), pixels, rowBytes, props); } internal SKSurface(IntPtr h, bool owns) : base(h, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(SKImageInfo, SKSurfaceProperties) instead.")] public static SKSurface Create(SKImageInfo info, SKSurfaceProps props) { return Create(info, 0, new SKSurfaceProperties(props)); } public static SKSurface Create(SKImageInfo info) { return Create(info, 0, null); } public static SKSurface Create(SKImageInfo info, int rowBytes) { return Create(info, rowBytes, null); } public static SKSurface Create(SKImageInfo info, SKSurfaceProperties props) { return Create(info, 0, props); } public unsafe static SKSurface Create(SKImageInfo info, int rowBytes, SKSurfaceProperties props) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return GetObject(SkiaApi.sk_surface_new_raster(&sKImageInfoNative, (IntPtr)rowBytes, props?.Handle ?? IntPtr.Zero)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(SKPixmap, SKSurfaceProperties) instead.")] public static SKSurface Create(SKPixmap pixmap, SKSurfaceProps props) { return Create(pixmap, new SKSurfaceProperties(props)); } public static SKSurface Create(SKPixmap pixmap) { return Create(pixmap, null); } public static SKSurface Create(SKPixmap pixmap, SKSurfaceProperties props) { if (pixmap == null) { throw new ArgumentNullException("pixmap"); } return Create(pixmap.Info, pixmap.GetPixels(), pixmap.RowBytes, null, null, props); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(SKImageInfo, IntPtr, rowBytes, SKSurfaceProperties) instead.")] public static SKSurface Create(SKImageInfo info, IntPtr pixels, int rowBytes, SKSurfaceProps props) { return Create(info, pixels, rowBytes, null, null, new SKSurfaceProperties(props)); } public static SKSurface Create(SKImageInfo info, IntPtr pixels) { return Create(info, pixels, info.RowBytes, null, null, null); } public static SKSurface Create(SKImageInfo info, IntPtr pixels, int rowBytes) { return Create(info, pixels, rowBytes, null, null, null); } public static SKSurface Create(SKImageInfo info, IntPtr pixels, int rowBytes, SKSurfaceReleaseDelegate releaseProc, object context) { return Create(info, pixels, rowBytes, releaseProc, context, null); } public static SKSurface Create(SKImageInfo info, IntPtr pixels, SKSurfaceProperties props) { return Create(info, pixels, info.RowBytes, null, null, props); } public static SKSurface Create(SKImageInfo info, IntPtr pixels, int rowBytes, SKSurfaceProperties props) { return Create(info, pixels, rowBytes, null, null, props); } public unsafe static SKSurface Create(SKImageInfo info, IntPtr pixels, int rowBytes, SKSurfaceReleaseDelegate releaseProc, object context, SKSurfaceProperties props) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); SKSurfaceReleaseDelegate managedDel = ((releaseProc != null && context != null) ? ((SKSurfaceReleaseDelegate)delegate(IntPtr addr, object _) { releaseProc(addr, context); }) : releaseProc); GCHandle gch; IntPtr contextPtr; SKSurfaceRasterReleaseProxyDelegate releaseProc2 = DelegateProxies.Create(managedDel, DelegateProxies.SKSurfaceReleaseDelegateProxy, out gch, out contextPtr); return GetObject(SkiaApi.sk_surface_new_raster_direct(&sKImageInfoNative, (void*)pixels, (IntPtr)rowBytes, releaseProc2, (void*)contextPtr, props?.Handle ?? IntPtr.Zero)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendRenderTarget, GRSurfaceOrigin, SKColorType) instead.")] public static SKSurface Create(GRContext context, GRBackendRenderTargetDesc desc) { if (context == null) { throw new ArgumentNullException("context"); } GRBackendRenderTarget renderTarget = new GRBackendRenderTarget(context.Backend, desc); return Create(context, renderTarget, desc.Origin, desc.Config.ToColorType(), null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendRenderTarget, GRSurfaceOrigin, SKColorType, SKSurfaceProperties) instead.")] public static SKSurface Create(GRContext context, GRBackendRenderTargetDesc desc, SKSurfaceProps props) { if (context == null) { throw new ArgumentNullException("context"); } GRBackendRenderTarget renderTarget = new GRBackendRenderTarget(context.Backend, desc); return Create(context, renderTarget, desc.Origin, desc.Config.ToColorType(), null, new SKSurfaceProperties(props)); } public static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, SKColorType colorType) { return Create((GRRecordingContext)context, renderTarget, colorType); } public static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType) { return Create((GRRecordingContext)context, renderTarget, origin, colorType); } public static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType, SKColorSpace colorspace) { return Create((GRRecordingContext)context, renderTarget, origin, colorType, colorspace); } public static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, SKColorType colorType, SKSurfaceProperties props) { return Create((GRRecordingContext)context, renderTarget, colorType, props); } public static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) { return Create((GRRecordingContext)context, renderTarget, origin, colorType, props); } public static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType, SKColorSpace colorspace, SKSurfaceProperties props) { return Create((GRRecordingContext)context, renderTarget, origin, colorType, colorspace, props); } public static SKSurface Create(GRRecordingContext context, GRBackendRenderTarget renderTarget, SKColorType colorType) { return Create(context, renderTarget, GRSurfaceOrigin.BottomLeft, colorType, null, null); } public static SKSurface Create(GRRecordingContext context, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType) { return Create(context, renderTarget, origin, colorType, null, null); } public static SKSurface Create(GRRecordingContext context, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType, SKColorSpace colorspace) { return Create(context, renderTarget, origin, colorType, colorspace, null); } public static SKSurface Create(GRRecordingContext context, GRBackendRenderTarget renderTarget, SKColorType colorType, SKSurfaceProperties props) { return Create(context, renderTarget, GRSurfaceOrigin.BottomLeft, colorType, null, props); } public static SKSurface Create(GRRecordingContext context, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) { return Create(context, renderTarget, origin, colorType, null, props); } public static SKSurface Create(GRRecordingContext context, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType, SKColorSpace colorspace, SKSurfaceProperties props) { if (context == null) { throw new ArgumentNullException("context"); } if (renderTarget == null) { throw new ArgumentNullException("renderTarget"); } return GetObject(SkiaApi.sk_surface_new_backend_render_target(context.Handle, renderTarget.Handle, origin, colorType.ToNative(), colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")] public static SKSurface Create(GRContext context, GRGlBackendTextureDesc desc) { return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType(), null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")] public static SKSurface Create(GRContext context, GRBackendTextureDesc desc) { return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType(), null, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")] public static SKSurface Create(GRContext context, GRGlBackendTextureDesc desc, SKSurfaceProps props) { return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType(), null, new SKSurfaceProperties(props)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")] public static SKSurface Create(GRContext context, GRBackendTextureDesc desc, SKSurfaceProps props) { return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType(), null, new SKSurfaceProperties(props)); } public static SKSurface Create(GRContext context, GRBackendTexture texture, SKColorType colorType) { return Create((GRRecordingContext)context, texture, colorType); } public static SKSurface Create(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) { return Create((GRRecordingContext)context, texture, origin, colorType); } public static SKSurface Create(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType) { return Create((GRRecordingContext)context, texture, origin, sampleCount, colorType); } public static SKSurface Create(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace) { return Create((GRRecordingContext)context, texture, origin, sampleCount, colorType, colorspace); } public static SKSurface Create(GRContext context, GRBackendTexture texture, SKColorType colorType, SKSurfaceProperties props) { return Create((GRRecordingContext)context, texture, colorType, props); } public static SKSurface Create(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) { return Create((GRRecordingContext)context, texture, origin, colorType, props); } public static SKSurface Create(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKSurfaceProperties props) { return Create((GRRecordingContext)context, texture, origin, sampleCount, colorType, props); } public static SKSurface Create(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace, SKSurfaceProperties props) { return Create((GRRecordingContext)context, texture, origin, sampleCount, colorType, colorspace, props); } public static SKSurface Create(GRRecordingContext context, GRBackendTexture texture, SKColorType colorType) { return Create(context, texture, GRSurfaceOrigin.BottomLeft, 0, colorType, null, null); } public static SKSurface Create(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) { return Create(context, texture, origin, 0, colorType, null, null); } public static SKSurface Create(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType) { return Create(context, texture, origin, sampleCount, colorType, null, null); } public static SKSurface Create(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace) { return Create(context, texture, origin, sampleCount, colorType, colorspace, null); } public static SKSurface Create(GRRecordingContext context, GRBackendTexture texture, SKColorType colorType, SKSurfaceProperties props) { return Create(context, texture, GRSurfaceOrigin.BottomLeft, 0, colorType, null, props); } public static SKSurface Create(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) { return Create(context, texture, origin, 0, colorType, null, props); } public static SKSurface Create(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKSurfaceProperties props) { return Create(context, texture, origin, sampleCount, colorType, null, props); } public static SKSurface Create(GRRecordingContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace, SKSurfaceProperties props) { if (context == null) { throw new ArgumentNullException("context"); } if (texture == null) { throw new ArgumentNullException("texture"); } return GetObject(SkiaApi.sk_surface_new_backend_texture(context.Handle, texture.Handle, origin, sampleCount, colorType.ToNative(), colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRGlBackendTextureDesc desc) { return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTextureDesc desc) { return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRGlBackendTextureDesc desc, SKSurfaceProps props) { return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType(), new SKSurfaceProperties(props)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTextureDesc desc, SKSurfaceProps props) { return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType(), new SKSurfaceProperties(props)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, SKColorType) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, SKColorType colorType) { return Create(context, texture, colorType); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) { return Create(context, texture, origin, colorType); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType) { return Create(context, texture, origin, sampleCount, colorType); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKColorSpace) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace) { return Create(context, texture, origin, sampleCount, colorType, colorspace); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, SKColorType, SKSurfaceProperties) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, SKColorType colorType, SKSurfaceProperties props) { return Create(context, texture, colorType, props); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKSurfaceProperties) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) { return Create(context, texture, origin, colorType, props); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKSurfaceProperties props) { return Create(context, texture, origin, sampleCount, colorType, null, props); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKColorSpace, SKSurfaceProperties) instead.")] public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace, SKSurfaceProperties props) { return Create(context, texture, origin, sampleCount, colorType, colorspace, props); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(GRContext, bool, SKImageInfo, int, SKSurfaceProperties) instead.")] public static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, int sampleCount, SKSurfaceProps props) { return Create(context, budgeted, info, sampleCount, GRSurfaceOrigin.BottomLeft, new SKSurfaceProperties(props), shouldCreateWithMips: false); } public static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info) { return Create((GRRecordingContext)context, budgeted, info); } public static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, int sampleCount) { return Create((GRRecordingContext)context, budgeted, info, sampleCount); } public static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, int sampleCount, GRSurfaceOrigin origin) { return Create((GRRecordingContext)context, budgeted, info, sampleCount, origin); } public static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, SKSurfaceProperties props) { return Create((GRRecordingContext)context, budgeted, info, props); } public static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, int sampleCount, SKSurfaceProperties props) { return Create((GRRecordingContext)context, budgeted, info, sampleCount, props); } public static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, int sampleCount, GRSurfaceOrigin origin, SKSurfaceProperties props, bool shouldCreateWithMips) { return Create((GRRecordingContext)context, budgeted, info, sampleCount, origin, props, shouldCreateWithMips: false); } public static SKSurface Create(GRRecordingContext context, bool budgeted, SKImageInfo info) { return Create(context, budgeted, info, 0, GRSurfaceOrigin.BottomLeft, null, shouldCreateWithMips: false); } public static SKSurface Create(GRRecordingContext context, bool budgeted, SKImageInfo info, int sampleCount) { return Create(context, budgeted, info, sampleCount, GRSurfaceOrigin.BottomLeft, null, shouldCreateWithMips: false); } public static SKSurface Create(GRRecordingContext context, bool budgeted, SKImageInfo info, int sampleCount, GRSurfaceOrigin origin) { return Create(context, budgeted, info, sampleCount, origin, null, shouldCreateWithMips: false); } public static SKSurface Create(GRRecordingContext context, bool budgeted, SKImageInfo info, SKSurfaceProperties props) { return Create(context, budgeted, info, 0, GRSurfaceOrigin.BottomLeft, props, shouldCreateWithMips: false); } public static SKSurface Create(GRRecordingContext context, bool budgeted, SKImageInfo info, int sampleCount, SKSurfaceProperties props) { return Create(context, budgeted, info, sampleCount, GRSurfaceOrigin.BottomLeft, props, shouldCreateWithMips: false); } public unsafe static SKSurface Create(GRRecordingContext context, bool budgeted, SKImageInfo info, int sampleCount, GRSurfaceOrigin origin, SKSurfaceProperties props, bool shouldCreateWithMips) { if (context == null) { throw new ArgumentNullException("context"); } SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref info); return GetObject(SkiaApi.sk_surface_new_render_target(context.Handle, budgeted, &sKImageInfoNative, sampleCount, origin, props?.Handle ?? IntPtr.Zero, shouldCreateWithMips)); } public static SKSurface CreateNull(int width, int height) { return GetObject(SkiaApi.sk_surface_new_null(width, height)); } public SKImage Snapshot() { return SKImage.GetObject(SkiaApi.sk_surface_new_image_snapshot(Handle)); } public unsafe SKImage Snapshot(SKRectI bounds) { return SKImage.GetObject(SkiaApi.sk_surface_new_image_snapshot_with_crop(Handle, &bounds)); } public void Draw(SKCanvas canvas, float x, float y, SKPaint paint) { if (canvas == null) { throw new ArgumentNullException("canvas"); } SkiaApi.sk_surface_draw(Handle, canvas.Handle, x, y, paint?.Handle ?? IntPtr.Zero); } public SKPixmap PeekPixels() { SKPixmap sKPixmap = new SKPixmap(); if (PeekPixels(sKPixmap)) { return sKPixmap; } sKPixmap.Dispose(); return null; } public bool PeekPixels(SKPixmap pixmap) { if (pixmap == null) { throw new ArgumentNullException("pixmap"); } bool flag = SkiaApi.sk_surface_peek_pixels(Handle, pixmap.Handle); if (flag) { pixmap.pixelSource = this; } return flag; } public unsafe bool ReadPixels(SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY) { SKImageInfoNative sKImageInfoNative = SKImageInfoNative.FromManaged(ref dstInfo); bool result = SkiaApi.sk_surface_read_pixels(Handle, &sKImageInfoNative, (void*)dstPixels, (IntPtr)dstRowBytes, srcX, srcY); GC.KeepAlive(this); return result; } public void Flush() { Flush(submit: true); } public void Flush(bool submit, bool synchronous = false) { if (submit) { SkiaApi.sk_surface_flush_and_submit(Handle, synchronous); } else { SkiaApi.sk_surface_flush(Handle); } } internal static SKSurface GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new SKSurface(handle, owns: true); } return null; } } public class SKSurfaceProperties : SKObject { public SKSurfacePropsFlags Flags => (SKSurfacePropsFlags)SkiaApi.sk_surfaceprops_get_flags(Handle); public SKPixelGeometry PixelGeometry => SkiaApi.sk_surfaceprops_get_pixel_geometry(Handle); public bool IsUseDeviceIndependentFonts => Flags.HasFlag(SKSurfacePropsFlags.UseDeviceIndependentFonts); internal SKSurfaceProperties(IntPtr h, bool owns) : base(h, owns) { } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public SKSurfaceProperties(SKSurfaceProps props) : this(props.Flags, props.PixelGeometry) { } public SKSurfaceProperties(SKPixelGeometry pixelGeometry) : this(0u, pixelGeometry) { } public SKSurfaceProperties(uint flags, SKPixelGeometry pixelGeometry) : this(SkiaApi.sk_surfaceprops_new(flags, pixelGeometry), owns: true) { } public SKSurfaceProperties(SKSurfacePropsFlags flags, SKPixelGeometry pixelGeometry) : this(SkiaApi.sk_surfaceprops_new((uint)flags, pixelGeometry), owns: true) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_surfaceprops_delete(Handle); } internal static SKSurfaceProperties GetObject(IntPtr handle, bool owns = true) { return SKObject.GetOrAddObject(handle, owns, (IntPtr h, bool o) => new SKSurfaceProperties(h, o)); } } public class SKSvgCanvas { private SKSvgCanvas() { } public static SKCanvas Create(SKRect bounds, Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } SKManagedWStream sKManagedWStream = new SKManagedWStream(stream); return SKObject.Owned(Create(bounds, sKManagedWStream), sKManagedWStream); } public unsafe static SKCanvas Create(SKRect bounds, SKWStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } return SKObject.Referenced(SKCanvas.GetObject(SkiaApi.sk_svgcanvas_create_with_stream(&bounds, stream.Handle)), stream); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use Create(SKRect, Stream) instead.")] public unsafe static SKCanvas Create(SKRect bounds, SKXmlWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } SKCanvas sKCanvas = SKCanvas.GetObject(SkiaApi.sk_svgcanvas_create_with_writer(&bounds, writer.Handle)); writer.RevokeOwnership(sKCanvas); return SKObject.Referenced(sKCanvas, writer); } } public static class SKSwizzle { public static void SwapRedBlue(IntPtr pixels, int count) { SwapRedBlue(pixels, pixels, count); } public unsafe static void SwapRedBlue(IntPtr dest, IntPtr src, int count) { if (dest == IntPtr.Zero) { throw new ArgumentException("dest"); } if (src == IntPtr.Zero) { throw new ArgumentException("src"); } SkiaApi.sk_swizzle_swap_rb((uint*)(void*)dest, (uint*)(void*)src, count); } public static void SwapRedBlue(Span pixels) { SwapRedBlue(pixels, pixels, pixels.Length); } public static void SwapRedBlue(ReadOnlySpan pixels, int count) { SwapRedBlue(pixels, pixels, count); } public unsafe static void SwapRedBlue(ReadOnlySpan dest, ReadOnlySpan src, int count) { if (dest == null) { throw new ArgumentNullException("dest"); } if (src == null) { throw new ArgumentNullException("src"); } fixed (byte* dest2 = dest) { fixed (byte* src2 = src) { SkiaApi.sk_swizzle_swap_rb((uint*)dest2, (uint*)src2, count); } } } } public class SKTextBlob : SKObject, ISKNonVirtualReferenceCounted, ISKReferenceCounted, ISKSkipObjectRegistration { public unsafe SKRect Bounds { get { SKRect result = default(SKRect); SkiaApi.sk_textblob_get_bounds(Handle, &result); return result; } } public uint UniqueId => SkiaApi.sk_textblob_get_unique_id(Handle); internal SKTextBlob(IntPtr x, bool owns) : base(x, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } void ISKNonVirtualReferenceCounted.ReferenceNative() { SkiaApi.sk_textblob_ref(Handle); } void ISKNonVirtualReferenceCounted.UnreferenceNative() { SkiaApi.sk_textblob_unref(Handle); } public static SKTextBlob Create(string text, SKFont font, SKPoint origin = default(SKPoint)) { return Create(text.AsSpan(), font, origin); } public unsafe static SKTextBlob Create(ReadOnlySpan text, SKFont font, SKPoint origin = default(SKPoint)) { fixed (char* ptr = text) { void* text2 = ptr; return Create(text2, text.Length * 2, SKTextEncoding.Utf16, font, origin); } } public static SKTextBlob Create(IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin = default(SKPoint)) { return Create(text.AsReadOnlySpan(length), encoding, font, origin); } public unsafe static SKTextBlob Create(ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPoint origin = default(SKPoint)) { fixed (byte* ptr = text) { void* text2 = ptr; return Create(text2, text.Length, encoding, font, origin); } } internal unsafe static SKTextBlob Create(void* text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin) { if (font == null) { throw new ArgumentNullException("font"); } int num = font.CountGlyphs(text, length, encoding); if (num <= 0) { return null; } using SKTextBlobBuilder sKTextBlobBuilder = new SKTextBlobBuilder(); SKPositionedRunBuffer sKPositionedRunBuffer = sKTextBlobBuilder.AllocatePositionedRun(font, num); font.GetGlyphs(text, length, encoding, sKPositionedRunBuffer.GetGlyphSpan()); font.GetGlyphPositions(sKPositionedRunBuffer.GetGlyphSpan(), sKPositionedRunBuffer.GetPositionSpan(), origin); return sKTextBlobBuilder.Build(); } public static SKTextBlob CreateHorizontal(string text, SKFont font, ReadOnlySpan positions, float y) { return CreateHorizontal(text.AsSpan(), font, positions, y); } public unsafe static SKTextBlob CreateHorizontal(ReadOnlySpan text, SKFont font, ReadOnlySpan positions, float y) { fixed (char* ptr = text) { void* text2 = ptr; return CreateHorizontal(text2, text.Length * 2, SKTextEncoding.Utf16, font, positions, y); } } public static SKTextBlob CreateHorizontal(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) { return CreateHorizontal(text.AsReadOnlySpan(length), encoding, font, positions, y); } public unsafe static SKTextBlob CreateHorizontal(ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) { fixed (byte* ptr = text) { void* text2 = ptr; return CreateHorizontal(text2, text.Length, encoding, font, positions, y); } } internal unsafe static SKTextBlob CreateHorizontal(void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) { if (font == null) { throw new ArgumentNullException("font"); } int num = font.CountGlyphs(text, length, encoding); if (num <= 0) { return null; } using SKTextBlobBuilder sKTextBlobBuilder = new SKTextBlobBuilder(); SKHorizontalRunBuffer sKHorizontalRunBuffer = sKTextBlobBuilder.AllocateHorizontalRun(font, num, y); font.GetGlyphs(text, length, encoding, sKHorizontalRunBuffer.GetGlyphSpan()); positions.CopyTo(sKHorizontalRunBuffer.GetPositionSpan()); return sKTextBlobBuilder.Build(); } public static SKTextBlob CreatePositioned(string text, SKFont font, ReadOnlySpan positions) { return CreatePositioned(text.AsSpan(), font, positions); } public unsafe static SKTextBlob CreatePositioned(ReadOnlySpan text, SKFont font, ReadOnlySpan positions) { fixed (char* ptr = text) { void* text2 = ptr; return CreatePositioned(text2, text.Length * 2, SKTextEncoding.Utf16, font, positions); } } public static SKTextBlob CreatePositioned(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { return CreatePositioned(text.AsReadOnlySpan(length), encoding, font, positions); } public unsafe static SKTextBlob CreatePositioned(ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { fixed (byte* ptr = text) { void* text2 = ptr; return CreatePositioned(text2, text.Length, encoding, font, positions); } } internal unsafe static SKTextBlob CreatePositioned(void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { if (font == null) { throw new ArgumentNullException("font"); } int num = font.CountGlyphs(text, length, encoding); if (num <= 0) { return null; } using SKTextBlobBuilder sKTextBlobBuilder = new SKTextBlobBuilder(); SKPositionedRunBuffer sKPositionedRunBuffer = sKTextBlobBuilder.AllocatePositionedRun(font, num); font.GetGlyphs(text, length, encoding, sKPositionedRunBuffer.GetGlyphSpan()); positions.CopyTo(sKPositionedRunBuffer.GetPositionSpan()); return sKTextBlobBuilder.Build(); } public static SKTextBlob CreateRotationScale(string text, SKFont font, ReadOnlySpan positions) { return CreateRotationScale(text.AsSpan(), font, positions); } public unsafe static SKTextBlob CreateRotationScale(ReadOnlySpan text, SKFont font, ReadOnlySpan positions) { fixed (char* ptr = text) { void* text2 = ptr; return CreateRotationScale(text2, text.Length * 2, SKTextEncoding.Utf16, font, positions); } } public static SKTextBlob CreateRotationScale(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { return CreateRotationScale(text.AsReadOnlySpan(length), encoding, font, positions); } public unsafe static SKTextBlob CreateRotationScale(ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { fixed (byte* ptr = text) { void* text2 = ptr; return CreateRotationScale(text2, text.Length, encoding, font, positions); } } internal unsafe static SKTextBlob CreateRotationScale(void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { if (font == null) { throw new ArgumentNullException("font"); } int num = font.CountGlyphs(text, length, encoding); if (num <= 0) { return null; } using SKTextBlobBuilder sKTextBlobBuilder = new SKTextBlobBuilder(); SKRotationScaleRunBuffer sKRotationScaleRunBuffer = sKTextBlobBuilder.AllocateRotationScaleRun(font, num); font.GetGlyphs(text, length, encoding, sKRotationScaleRunBuffer.GetGlyphSpan()); positions.CopyTo(sKRotationScaleRunBuffer.GetRotationScaleSpan()); return sKTextBlobBuilder.Build(); } public static SKTextBlob CreatePathPositioned(string text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { return CreatePathPositioned(text.AsSpan(), font, path, textAlign, origin); } public unsafe static SKTextBlob CreatePathPositioned(ReadOnlySpan text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { fixed (char* ptr = text) { void* text2 = ptr; return CreatePathPositioned(text2, text.Length * 2, SKTextEncoding.Utf16, font, path, textAlign, origin); } } public static SKTextBlob CreatePathPositioned(IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { return CreatePathPositioned(text.AsReadOnlySpan(length), encoding, font, path, textAlign, origin); } public unsafe static SKTextBlob CreatePathPositioned(ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { fixed (byte* ptr = text) { void* text2 = ptr; return CreatePathPositioned(text2, text.Length, encoding, font, path, textAlign, origin); } } internal unsafe static SKTextBlob CreatePathPositioned(void* text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default(SKPoint)) { if (font == null) { throw new ArgumentNullException("font"); } int num = font.CountGlyphs(text, length, encoding); if (num <= 0) { return null; } Utils.RentedArray rentedArray = Utils.RentArray(num); try { Utils.RentedArray rentedArray2 = Utils.RentArray(rentedArray.Length); try { Utils.RentedArray rentedArray3 = Utils.RentArray(rentedArray.Length); try { font.GetGlyphs(text, length, encoding, rentedArray); font.GetGlyphWidths(rentedArray, rentedArray2, Span.Empty); font.GetGlyphPositions(rentedArray, rentedArray3, origin); using SKTextBlobBuilder sKTextBlobBuilder = new SKTextBlobBuilder(); sKTextBlobBuilder.AddPathPositionedRun(rentedArray, font, rentedArray2, rentedArray3, path, textAlign); return sKTextBlobBuilder.Build(); } finally { rentedArray3.Dispose(); } } finally { rentedArray2.Dispose(); } } finally { rentedArray.Dispose(); } } public float[] GetIntercepts(float upperBounds, float lowerBounds, SKPaint paint = null) { int num = CountIntercepts(upperBounds, lowerBounds, paint); float[] array = new float[num]; GetIntercepts(upperBounds, lowerBounds, array, paint); return array; } public unsafe void GetIntercepts(float upperBounds, float lowerBounds, Span intervals, SKPaint paint = null) { float* ptr = stackalloc float[2]; *ptr = upperBounds; ptr[1] = lowerBounds; fixed (float* intervals2 = intervals) { SkiaApi.sk_textblob_get_intercepts(Handle, ptr, intervals2, paint?.Handle ?? IntPtr.Zero); } } public unsafe int CountIntercepts(float upperBounds, float lowerBounds, SKPaint paint = null) { float* ptr = stackalloc float[2]; *ptr = upperBounds; ptr[1] = lowerBounds; return SkiaApi.sk_textblob_get_intercepts(Handle, ptr, null, paint?.Handle ?? IntPtr.Zero); } internal static SKTextBlob GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new SKTextBlob(handle, owns: true); } return null; } } public class SKTextBlobBuilder : SKObject, ISKSkipObjectRegistration { internal SKTextBlobBuilder(IntPtr x, bool owns) : base(x, owns) { } public SKTextBlobBuilder() : this(SkiaApi.sk_textblob_builder_new(), owns: true) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_textblob_builder_delete(Handle); } public SKTextBlob Build() { SKTextBlob result = SKTextBlob.GetObject(SkiaApi.sk_textblob_builder_make(Handle)); GC.KeepAlive(this); return result; } public void AddRun(ReadOnlySpan glyphs, SKFont font, SKPoint origin = default(SKPoint)) { if (font == null) { throw new ArgumentNullException("font"); } SKPositionedRunBuffer sKPositionedRunBuffer = AllocatePositionedRun(font, glyphs.Length); glyphs.CopyTo(sKPositionedRunBuffer.GetGlyphSpan()); font.GetGlyphPositions(sKPositionedRunBuffer.GetGlyphSpan(), sKPositionedRunBuffer.GetPositionSpan(), origin); } public void AddHorizontalRun(ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions, float y) { if (font == null) { throw new ArgumentNullException("font"); } SKHorizontalRunBuffer sKHorizontalRunBuffer = AllocateHorizontalRun(font, glyphs.Length, y); glyphs.CopyTo(sKHorizontalRunBuffer.GetGlyphSpan()); positions.CopyTo(sKHorizontalRunBuffer.GetPositionSpan()); } public void AddPositionedRun(ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions) { if (font == null) { throw new ArgumentNullException("font"); } SKPositionedRunBuffer sKPositionedRunBuffer = AllocatePositionedRun(font, glyphs.Length); glyphs.CopyTo(sKPositionedRunBuffer.GetGlyphSpan()); positions.CopyTo(sKPositionedRunBuffer.GetPositionSpan()); } public void AddRotationScaleRun(ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions) { if (font == null) { throw new ArgumentNullException("font"); } SKRotationScaleRunBuffer sKRotationScaleRunBuffer = AllocateRotationScaleRun(font, glyphs.Length); glyphs.CopyTo(sKRotationScaleRunBuffer.GetGlyphSpan()); positions.CopyTo(sKRotationScaleRunBuffer.GetRotationScaleSpan()); } public void AddPathPositionedRun(ReadOnlySpan glyphs, SKFont font, ReadOnlySpan glyphWidths, ReadOnlySpan glyphOffsets, SKPath path, SKTextAlign textAlign = SKTextAlign.Left) { using SKPathMeasure sKPathMeasure = new SKPathMeasure(path); float length = sKPathMeasure.Length; float num = glyphOffsets[glyphs.Length - 1].X + glyphWidths[glyphs.Length - 1]; float num2 = (float)textAlign * 0.5f; float num3 = glyphOffsets[0].X + (length - num) * num2; int start = 0; int num4 = 0; Utils.RentedArray rentedArray = Utils.RentArray(glyphs.Length); try { for (int i = 0; i < glyphOffsets.Length; i++) { SKPoint sKPoint = glyphOffsets[i]; float num5 = glyphWidths[i] * 0.5f; float num6 = num3 + sKPoint.X + num5; if (num6 >= 0f && num6 < length && sKPathMeasure.GetPositionAndTangent(num6, out var position, out var tangent)) { if (num4 == 0) { start = i; } float x = tangent.X; float y = tangent.Y; float x2 = position.X; float y2 = position.Y; x2 -= x * num5; y2 -= y * num5; float y3 = sKPoint.Y; x2 -= y3 * y; y2 += y3 * x; rentedArray.Span[num4++] = new SKRotationScaleMatrix(x, y, x2, y2); } } ReadOnlySpan glyphs2 = glyphs.Slice(start, num4); Span span = rentedArray.Span.Slice(0, num4); AddRotationScaleRun(glyphs2, font, span); } finally { rentedArray.Dispose(); } } public unsafe SKRunBuffer AllocateRun(SKFont font, int count, float x, float y, SKRect? bounds = null) { if (font == null) { throw new ArgumentNullException("font"); } SKRunBufferInternal buffer = default(SKRunBufferInternal); if (bounds.HasValue) { SKRect valueOrDefault = bounds.GetValueOrDefault(); SkiaApi.sk_textblob_builder_alloc_run(Handle, font.Handle, count, x, y, &valueOrDefault, &buffer); } else { SkiaApi.sk_textblob_builder_alloc_run(Handle, font.Handle, count, x, y, null, &buffer); } return new SKRunBuffer(buffer, count); } public unsafe SKHorizontalRunBuffer AllocateHorizontalRun(SKFont font, int count, float y, SKRect? bounds = null) { if (font == null) { throw new ArgumentNullException("font"); } SKRunBufferInternal buffer = default(SKRunBufferInternal); if (bounds.HasValue) { SKRect valueOrDefault = bounds.GetValueOrDefault(); SkiaApi.sk_textblob_builder_alloc_run_pos_h(Handle, font.Handle, count, y, &valueOrDefault, &buffer); } else { SkiaApi.sk_textblob_builder_alloc_run_pos_h(Handle, font.Handle, count, y, null, &buffer); } return new SKHorizontalRunBuffer(buffer, count); } public unsafe SKPositionedRunBuffer AllocatePositionedRun(SKFont font, int count, SKRect? bounds = null) { if (font == null) { throw new ArgumentNullException("font"); } SKRunBufferInternal buffer = default(SKRunBufferInternal); if (bounds.HasValue) { SKRect valueOrDefault = bounds.GetValueOrDefault(); SkiaApi.sk_textblob_builder_alloc_run_pos(Handle, font.Handle, count, &valueOrDefault, &buffer); } else { SkiaApi.sk_textblob_builder_alloc_run_pos(Handle, font.Handle, count, null, &buffer); } return new SKPositionedRunBuffer(buffer, count); } public unsafe SKRotationScaleRunBuffer AllocateRotationScaleRun(SKFont font, int count) { if (font == null) { throw new ArgumentNullException("font"); } SKRunBufferInternal buffer = default(SKRunBufferInternal); SkiaApi.sk_textblob_builder_alloc_run_rsxform(Handle, font.Handle, count, &buffer); return new SKRotationScaleRunBuffer(buffer, count); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ushort[] glyphs, string text, uint[] clusters) { byte[] encodedText = StringUtilities.GetEncodedText(text, SKTextEncoding.Utf8); AddRun(font, x, y, glyphs, encodedText, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ushort[] glyphs, string text, uint[] clusters, SKRect bounds) { byte[] encodedText = StringUtilities.GetEncodedText(text, SKTextEncoding.Utf8); AddRun(font, x, y, (ReadOnlySpan)glyphs, (ReadOnlySpan)encodedText, (ReadOnlySpan)clusters, (SKRect?)bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ushort[] glyphs) { AddRun(font, x, y, glyphs, ReadOnlySpan.Empty, ReadOnlySpan.Empty, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ushort[] glyphs, SKRect bounds) { AddRun(font, x, y, glyphs, ReadOnlySpan.Empty, ReadOnlySpan.Empty, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ushort[] glyphs, byte[] text, uint[] clusters) { AddRun(font, x, y, glyphs, text, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ushort[] glyphs, byte[] text, uint[] clusters, SKRect bounds) { AddRun(font, x, y, (ReadOnlySpan)glyphs, (ReadOnlySpan)text, (ReadOnlySpan)clusters, (SKRect?)bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ReadOnlySpan glyphs) { AddRun(font, x, y, glyphs, ReadOnlySpan.Empty, ReadOnlySpan.Empty, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ReadOnlySpan glyphs, SKRect? bounds) { AddRun(font, x, y, glyphs, ReadOnlySpan.Empty, ReadOnlySpan.Empty, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ReadOnlySpan glyphs, ReadOnlySpan text, ReadOnlySpan clusters) { AddRun(font, x, y, glyphs, text, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddRun (ReadOnlySpan, SKFont, float, float) instead.")] public void AddRun(SKPaint font, float x, float y, ReadOnlySpan glyphs, ReadOnlySpan text, ReadOnlySpan clusters, SKRect? bounds) { if (font == null) { throw new ArgumentNullException("font"); } if (glyphs.IsEmpty) { throw new ArgumentNullException("glyphs"); } if (!text.IsEmpty) { if (clusters.IsEmpty) { throw new ArgumentNullException("clusters"); } if (glyphs.Length != clusters.Length) { throw new ArgumentException("The number of glyphs and clusters must be the same."); } } SKRunBuffer sKRunBuffer = AllocateRun(font, glyphs.Length, x, y, (!text.IsEmpty) ? text.Length : 0, bounds); sKRunBuffer.SetGlyphs(glyphs); if (!text.IsEmpty) { sKRunBuffer.SetText(text); sKRunBuffer.SetClusters(clusters); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ushort[] glyphs, float[] positions, string text, uint[] clusters) { byte[] encodedText = StringUtilities.GetEncodedText(text, SKTextEncoding.Utf8); AddHorizontalRun(font, y, glyphs, positions, encodedText, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ushort[] glyphs, float[] positions, string text, uint[] clusters, SKRect bounds) { byte[] encodedText = StringUtilities.GetEncodedText(text, SKTextEncoding.Utf8); AddHorizontalRun(font, y, (ReadOnlySpan)glyphs, (ReadOnlySpan)positions, (ReadOnlySpan)encodedText, (ReadOnlySpan)clusters, (SKRect?)bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ushort[] glyphs, float[] positions) { AddHorizontalRun(font, y, glyphs, positions, ReadOnlySpan.Empty, ReadOnlySpan.Empty, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ushort[] glyphs, float[] positions, SKRect bounds) { AddHorizontalRun(font, y, glyphs, positions, ReadOnlySpan.Empty, ReadOnlySpan.Empty, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ushort[] glyphs, float[] positions, byte[] text, uint[] clusters) { AddHorizontalRun(font, y, glyphs, positions, text, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ushort[] glyphs, float[] positions, byte[] text, uint[] clusters, SKRect bounds) { AddHorizontalRun(font, y, (ReadOnlySpan)glyphs, (ReadOnlySpan)positions, (ReadOnlySpan)text, (ReadOnlySpan)clusters, (SKRect?)bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ReadOnlySpan glyphs, ReadOnlySpan positions) { AddHorizontalRun(font, y, glyphs, positions, ReadOnlySpan.Empty, ReadOnlySpan.Empty, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ReadOnlySpan glyphs, ReadOnlySpan positions, SKRect? bounds) { AddHorizontalRun(font, y, glyphs, positions, ReadOnlySpan.Empty, ReadOnlySpan.Empty, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ReadOnlySpan glyphs, ReadOnlySpan positions, ReadOnlySpan text, ReadOnlySpan clusters) { AddHorizontalRun(font, y, glyphs, positions, text, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddHorizontalRun (ReadOnlySpan, SKFont, ReadOnlySpan, float) instead.")] public void AddHorizontalRun(SKPaint font, float y, ReadOnlySpan glyphs, ReadOnlySpan positions, ReadOnlySpan text, ReadOnlySpan clusters, SKRect? bounds) { if (font == null) { throw new ArgumentNullException("font"); } if (glyphs.IsEmpty) { throw new ArgumentNullException("glyphs"); } if (positions.IsEmpty) { throw new ArgumentNullException("positions"); } if (glyphs.Length != positions.Length) { throw new ArgumentException("The number of glyphs and positions must be the same."); } if (!text.IsEmpty) { if (clusters.IsEmpty) { throw new ArgumentNullException("clusters"); } if (glyphs.Length != clusters.Length) { throw new ArgumentException("The number of glyphs and clusters must be the same."); } } SKHorizontalRunBuffer sKHorizontalRunBuffer = AllocateHorizontalRun(font, glyphs.Length, y, (!text.IsEmpty) ? text.Length : 0, bounds); sKHorizontalRunBuffer.SetGlyphs(glyphs); sKHorizontalRunBuffer.SetPositions(positions); if (!text.IsEmpty) { sKHorizontalRunBuffer.SetText(text); sKHorizontalRunBuffer.SetClusters(clusters); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ushort[] glyphs, SKPoint[] positions, string text, uint[] clusters) { byte[] encodedText = StringUtilities.GetEncodedText(text, SKTextEncoding.Utf8); AddPositionedRun(font, glyphs, positions, encodedText, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ushort[] glyphs, SKPoint[] positions, string text, uint[] clusters, SKRect bounds) { byte[] encodedText = StringUtilities.GetEncodedText(text, SKTextEncoding.Utf8); AddPositionedRun(font, (ReadOnlySpan)glyphs, (ReadOnlySpan)positions, (ReadOnlySpan)encodedText, (ReadOnlySpan)clusters, (SKRect?)bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ushort[] glyphs, SKPoint[] positions) { AddPositionedRun(font, glyphs, positions, ReadOnlySpan.Empty, ReadOnlySpan.Empty, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ushort[] glyphs, SKPoint[] positions, SKRect bounds) { AddPositionedRun(font, glyphs, positions, ReadOnlySpan.Empty, ReadOnlySpan.Empty, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ushort[] glyphs, SKPoint[] positions, byte[] text, uint[] clusters) { AddPositionedRun(font, glyphs, positions, text, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ushort[] glyphs, SKPoint[] positions, byte[] text, uint[] clusters, SKRect bounds) { AddPositionedRun(font, (ReadOnlySpan)glyphs, (ReadOnlySpan)positions, (ReadOnlySpan)text, (ReadOnlySpan)clusters, (SKRect?)bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ReadOnlySpan glyphs, ReadOnlySpan positions) { AddPositionedRun(font, glyphs, positions, ReadOnlySpan.Empty, ReadOnlySpan.Empty, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ReadOnlySpan glyphs, ReadOnlySpan positions, SKRect? bounds) { AddPositionedRun(font, glyphs, positions, ReadOnlySpan.Empty, ReadOnlySpan.Empty, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ReadOnlySpan glyphs, ReadOnlySpan positions, ReadOnlySpan text, ReadOnlySpan clusters) { AddPositionedRun(font, glyphs, positions, text, clusters, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AddPositionedRun (ReadOnlySpan, SKFont, ReadOnlySpan) instead.")] public void AddPositionedRun(SKPaint font, ReadOnlySpan glyphs, ReadOnlySpan positions, ReadOnlySpan text, ReadOnlySpan clusters, SKRect? bounds) { if (font == null) { throw new ArgumentNullException("font"); } if (glyphs.IsEmpty) { throw new ArgumentNullException("glyphs"); } if (positions.IsEmpty) { throw new ArgumentNullException("positions"); } if (glyphs.Length != positions.Length) { throw new ArgumentException("The number of glyphs and positions must be the same."); } if (!text.IsEmpty) { if (clusters.IsEmpty) { throw new ArgumentNullException("clusters"); } if (glyphs.Length != clusters.Length) { throw new ArgumentException("The number of glyphs and clusters must be the same."); } } SKPositionedRunBuffer sKPositionedRunBuffer = AllocatePositionedRun(font, glyphs.Length, (!text.IsEmpty) ? text.Length : 0, bounds); sKPositionedRunBuffer.SetGlyphs(glyphs); sKPositionedRunBuffer.SetPositions(positions); if (!text.IsEmpty) { sKPositionedRunBuffer.SetText(text); sKPositionedRunBuffer.SetClusters(clusters); } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocateRun (SKFont, int, float, float, SKRect?) instead.")] public SKRunBuffer AllocateRun(SKPaint font, int count, float x, float y) { return AllocateRun(font, count, x, y, 0, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocateRun (SKFont, int, float, float, SKRect?) instead.")] public SKRunBuffer AllocateRun(SKPaint font, int count, float x, float y, SKRect? bounds) { return AllocateRun(font, count, x, y, 0, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocateRun (SKFont, int, float, float, SKRect?) instead.")] public SKRunBuffer AllocateRun(SKPaint font, int count, float x, float y, int textByteCount) { return AllocateRun(font, count, x, y, textByteCount, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocateRun (SKFont, int, float, float, SKRect?) instead.")] public unsafe SKRunBuffer AllocateRun(SKPaint font, int count, float x, float y, int textByteCount, SKRect? bounds) { if (font == null) { throw new ArgumentNullException("font"); } SKTextEncoding textEncoding = font.TextEncoding; try { font.TextEncoding = SKTextEncoding.GlyphId; SKRunBufferInternal buffer = default(SKRunBufferInternal); if (bounds.HasValue) { SKRect valueOrDefault = bounds.GetValueOrDefault(); SkiaApi.sk_textblob_builder_alloc_run_text(Handle, font.GetFont().Handle, count, x, y, textByteCount, &valueOrDefault, &buffer); } else { SkiaApi.sk_textblob_builder_alloc_run_text(Handle, font.GetFont().Handle, count, x, y, textByteCount, null, &buffer); } return new SKRunBuffer(buffer, count, textByteCount); } finally { font.TextEncoding = textEncoding; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocateHorizontalRun (SKFont, int, float, SKRect?) instead.")] public SKHorizontalRunBuffer AllocateHorizontalRun(SKPaint font, int count, float y) { return AllocateHorizontalRun(font, count, y, 0, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocateHorizontalRun (SKFont, int, float, SKRect?) instead.")] public SKHorizontalRunBuffer AllocateHorizontalRun(SKPaint font, int count, float y, SKRect? bounds) { return AllocateHorizontalRun(font, count, y, 0, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocateHorizontalRun (SKFont, int, float, SKRect?) instead.")] public SKHorizontalRunBuffer AllocateHorizontalRun(SKPaint font, int count, float y, int textByteCount) { return AllocateHorizontalRun(font, count, y, textByteCount, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocateHorizontalRun (SKFont, int, float, SKRect?) instead.")] public unsafe SKHorizontalRunBuffer AllocateHorizontalRun(SKPaint font, int count, float y, int textByteCount, SKRect? bounds) { if (font == null) { throw new ArgumentNullException("font"); } SKTextEncoding textEncoding = font.TextEncoding; try { font.TextEncoding = SKTextEncoding.GlyphId; SKRunBufferInternal buffer = default(SKRunBufferInternal); if (bounds.HasValue) { SKRect valueOrDefault = bounds.GetValueOrDefault(); SkiaApi.sk_textblob_builder_alloc_run_text_pos_h(Handle, font.GetFont().Handle, count, y, textByteCount, &valueOrDefault, &buffer); } else { SkiaApi.sk_textblob_builder_alloc_run_text_pos_h(Handle, font.GetFont().Handle, count, y, textByteCount, null, &buffer); } return new SKHorizontalRunBuffer(buffer, count, textByteCount); } finally { font.TextEncoding = textEncoding; } } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocatePositionedRun (SKFont, int, SKRect?) instead.")] public SKPositionedRunBuffer AllocatePositionedRun(SKPaint font, int count) { return AllocatePositionedRun(font, count, 0, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocatePositionedRun (SKFont, int, SKRect?) instead.")] public SKPositionedRunBuffer AllocatePositionedRun(SKPaint font, int count, SKRect? bounds) { return AllocatePositionedRun(font, count, 0, bounds); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocatePositionedRun (SKFont, int, SKRect?) instead.")] public SKPositionedRunBuffer AllocatePositionedRun(SKPaint font, int count, int textByteCount) { return AllocatePositionedRun(font, count, textByteCount, null); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use AllocatePositionedRun (SKFont, int, SKRect?) instead.")] public unsafe SKPositionedRunBuffer AllocatePositionedRun(SKPaint font, int count, int textByteCount, SKRect? bounds) { if (font == null) { throw new ArgumentNullException("font"); } SKTextEncoding textEncoding = font.TextEncoding; try { font.TextEncoding = SKTextEncoding.GlyphId; SKRunBufferInternal buffer = default(SKRunBufferInternal); if (bounds.HasValue) { SKRect valueOrDefault = bounds.GetValueOrDefault(); SkiaApi.sk_textblob_builder_alloc_run_text_pos(Handle, font.GetFont().Handle, count, textByteCount, &valueOrDefault, &buffer); } else { SkiaApi.sk_textblob_builder_alloc_run_text_pos(Handle, font.GetFont().Handle, count, textByteCount, null, &buffer); } return new SKPositionedRunBuffer(buffer, count, textByteCount); } finally { font.TextEncoding = textEncoding; } } } public class SKTraceMemoryDump : SKObject, ISKSkipObjectRegistration { private static readonly SKManagedTraceMemoryDumpDelegates delegates; private readonly IntPtr userData; unsafe static SKTraceMemoryDump() { delegates = new SKManagedTraceMemoryDumpDelegates { fDumpNumericValue = DumpNumericValueInternal, fDumpStringValue = DumpStringValueInternal }; SkiaApi.sk_managedtracememorydump_set_procs(delegates); } protected unsafe SKTraceMemoryDump(bool detailedDump, bool dumpWrappedObjects) : base(IntPtr.Zero, owns: true) { userData = DelegateProxies.CreateUserData(this, makeWeak: true); Handle = SkiaApi.sk_managedtracememorydump_new(detailedDump, dumpWrappedObjects, (void*)userData); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKTraceMemoryDump instance."); } } protected override void DisposeNative() { DelegateProxies.GetUserData(userData, out var gch); SkiaApi.sk_managedtracememorydump_delete(Handle); gch.Free(); } protected virtual void OnDumpNumericValue(string dumpName, string valueName, string units, ulong value) { } protected virtual void OnDumpStringValue(string dumpName, string valueName, string value) { } [MonoPInvokeCallback(typeof(SKManagedTraceMemoryDumpDumpNumericValueProxyDelegate))] private unsafe static void DumpNumericValueInternal(IntPtr d, void* context, void* dumpName, void* valueName, void* units, ulong value) { GCHandle gch; SKTraceMemoryDump sKTraceMemoryDump = DelegateProxies.GetUserData((IntPtr)context, out gch); sKTraceMemoryDump.OnDumpNumericValue(Marshal.PtrToStringAnsi((IntPtr)dumpName), Marshal.PtrToStringAnsi((IntPtr)valueName), Marshal.PtrToStringAnsi((IntPtr)units), value); } [MonoPInvokeCallback(typeof(SKManagedTraceMemoryDumpDumpStringValueProxyDelegate))] private unsafe static void DumpStringValueInternal(IntPtr d, void* context, void* dumpName, void* valueName, void* value) { GCHandle gch; SKTraceMemoryDump sKTraceMemoryDump = DelegateProxies.GetUserData((IntPtr)context, out gch); sKTraceMemoryDump.OnDumpStringValue(Marshal.PtrToStringAnsi((IntPtr)dumpName), Marshal.PtrToStringAnsi((IntPtr)valueName), Marshal.PtrToStringAnsi((IntPtr)value)); } } [EditorBrowsable(EditorBrowsableState.Never)] [Flags] [Obsolete("Use SKFontStyleWeight and SKFontStyleSlant instead.")] public enum SKTypefaceStyle { Normal = 0, Bold = 1, Italic = 2, BoldItalic = 3 } public class SKTypeface : SKObject, ISKReferenceCounted { private sealed class SKTypefaceStatic : SKTypeface { internal SKTypefaceStatic(IntPtr x) : base(x, owns: false) { } protected override void Dispose(bool disposing) { } } private static readonly SKTypeface defaultTypeface; private SKFont font; public static SKTypeface Default => defaultTypeface; public string FamilyName => (string)SKString.GetObject(SkiaApi.sk_typeface_get_family_name(Handle)); public SKFontStyle FontStyle => SKFontStyle.GetObject(SkiaApi.sk_typeface_get_fontstyle(Handle)); public int FontWeight => SkiaApi.sk_typeface_get_font_weight(Handle); public int FontWidth => SkiaApi.sk_typeface_get_font_width(Handle); public SKFontStyleSlant FontSlant => SkiaApi.sk_typeface_get_font_slant(Handle); public bool IsBold => FontStyle.Weight >= 600; public bool IsItalic => FontStyle.Slant != SKFontStyleSlant.Upright; public bool IsFixedPitch => SkiaApi.sk_typeface_is_fixed_pitch(Handle); [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FontWeight and FontSlant instead.")] public SKTypefaceStyle Style { get { SKTypefaceStyle sKTypefaceStyle = SKTypefaceStyle.Normal; if (FontWeight >= 600) { sKTypefaceStyle |= SKTypefaceStyle.Bold; } if (FontSlant != SKFontStyleSlant.Upright) { sKTypefaceStyle |= SKTypefaceStyle.Italic; } return sKTypefaceStyle; } } public int UnitsPerEm => SkiaApi.sk_typeface_get_units_per_em(Handle); public int GlyphCount => SkiaApi.sk_typeface_count_glyphs(Handle); public int TableCount => SkiaApi.sk_typeface_count_tables(Handle); static SKTypeface() { defaultTypeface = new SKTypefaceStatic(SkiaApi.sk_typeface_ref_default()); } internal static void EnsureStaticInstanceAreInitialized() { } internal SKTypeface(IntPtr handle, bool owns) : base(handle, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public static SKTypeface CreateDefault() { return GetObject(SkiaApi.sk_typeface_create_default()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use FromFamilyName(string, SKFontStyleWeight, SKFontStyleWidth, SKFontStyleSlant) instead.")] public static SKTypeface FromFamilyName(string familyName, SKTypefaceStyle style) { SKFontStyleWeight weight = (style.HasFlag(SKTypefaceStyle.Bold) ? SKFontStyleWeight.Bold : SKFontStyleWeight.Normal); SKFontStyleSlant slant = (style.HasFlag(SKTypefaceStyle.Italic) ? SKFontStyleSlant.Italic : SKFontStyleSlant.Upright); return FromFamilyName(familyName, weight, SKFontStyleWidth.Normal, slant); } public static SKTypeface FromFamilyName(string familyName, int weight, int width, SKFontStyleSlant slant) { return FromFamilyName(familyName, new SKFontStyle(weight, width, slant)); } public static SKTypeface FromFamilyName(string familyName) { return FromFamilyName(familyName, SKFontStyle.Normal); } public unsafe static SKTypeface FromFamilyName(string familyName, SKFontStyle style) { if (style == null) { throw new ArgumentNullException("style"); } fixed (byte* encodedText = StringUtilities.GetEncodedText(familyName, SKTextEncoding.Utf8, addNull: true)) { SKTypeface sKTypeface = GetObject(SkiaApi.sk_typeface_create_from_name(new IntPtr(encodedText), style.Handle)); sKTypeface?.PreventPublicDisposal(); return sKTypeface; } } public static SKTypeface FromFamilyName(string familyName, SKFontStyleWeight weight, SKFontStyleWidth width, SKFontStyleSlant slant) { return FromFamilyName(familyName, (int)weight, (int)width, slant); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete] public static SKTypeface FromTypeface(SKTypeface typeface, SKTypefaceStyle style) { if (typeface == null) { throw new ArgumentNullException("typeface"); } SKFontStyleWeight weight = (style.HasFlag(SKTypefaceStyle.Bold) ? SKFontStyleWeight.Bold : SKFontStyleWeight.Normal); SKFontStyleWidth width = SKFontStyleWidth.Normal; SKFontStyleSlant slant = (style.HasFlag(SKTypefaceStyle.Italic) ? SKFontStyleSlant.Italic : SKFontStyleSlant.Upright); return SKFontManager.Default.MatchTypeface(typeface, new SKFontStyle(weight, width, slant)); } public unsafe static SKTypeface FromFile(string path, int index = 0) { if (path == null) { throw new ArgumentNullException("path"); } fixed (byte* encodedText = StringUtilities.GetEncodedText(path, SKTextEncoding.Utf8, addNull: true)) { return GetObject(SkiaApi.sk_typeface_create_from_file(encodedText, index)); } } public static SKTypeface FromStream(Stream stream, int index = 0) { if (stream == null) { throw new ArgumentNullException("stream"); } return FromStream(new SKManagedStream(stream, disposeManagedStream: true), index); } public static SKTypeface FromStream(SKStreamAsset stream, int index = 0) { if (stream == null) { throw new ArgumentNullException("stream"); } if (stream is SKManagedStream sKManagedStream) { stream = sKManagedStream.ToMemoryStream(); sKManagedStream.Dispose(); } SKTypeface sKTypeface = GetObject(SkiaApi.sk_typeface_create_from_stream(stream.Handle, index)); stream.RevokeOwnership(sKTypeface); return sKTypeface; } public static SKTypeface FromData(SKData data, int index = 0) { if (data == null) { throw new ArgumentNullException("data"); } return GetObject(SkiaApi.sk_typeface_create_from_data(data.Handle, index)); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(string, out ushort[]) instead.")] public int CharsToGlyphs(string chars, out ushort[] glyphs) { return GetGlyphs(chars, out glyphs); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(IntPtr, int, SKTextEncoding, out ushort[]) instead.")] public int CharsToGlyphs(IntPtr str, int strlen, SKEncoding encoding, out ushort[] glyphs) { return GetGlyphs(str, strlen, encoding, out glyphs); } public uint[] GetTableTags() { if (!TryGetTableTags(out var tags)) { throw new Exception("Unable to read the tables for the file."); } return tags; } public unsafe bool TryGetTableTags(out uint[] tags) { uint[] array = new uint[TableCount]; fixed (uint* tags2 = array) { if (SkiaApi.sk_typeface_get_table_tags(Handle, tags2) == 0) { tags = null; return false; } } tags = array; return true; } public int GetTableSize(uint tag) { return (int)SkiaApi.sk_typeface_get_table_size(Handle, tag); } public byte[] GetTableData(uint tag) { if (!TryGetTableData(tag, out var tableData)) { throw new Exception("Unable to read the data table."); } return tableData; } public unsafe bool TryGetTableData(uint tag, out byte[] tableData) { int tableSize = GetTableSize(tag); byte[] array = new byte[tableSize]; fixed (byte* ptr = array) { if (!TryGetTableData(tag, 0, tableSize, (IntPtr)ptr)) { tableData = null; return false; } } tableData = array; return true; } public unsafe bool TryGetTableData(uint tag, int offset, int length, IntPtr tableData) { IntPtr intPtr = SkiaApi.sk_typeface_get_table_data(Handle, tag, (IntPtr)offset, (IntPtr)length, (void*)tableData); return intPtr != IntPtr.Zero; } public int CountGlyphs(string str) { return GetFont().CountGlyphs(str); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CountGlyphs(string) instead.")] public int CountGlyphs(string str, SKEncoding encoding) { return GetFont().CountGlyphs(str); } public int CountGlyphs(ReadOnlySpan str) { return GetFont().CountGlyphs(str); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CountGlyphs(byte[], SKTextEncoding) instead.")] public int CountGlyphs(byte[] str, SKEncoding encoding) { return GetFont().CountGlyphs(str, encoding.ToTextEncoding()); } public int CountGlyphs(byte[] str, SKTextEncoding encoding) { return GetFont().CountGlyphs(str, encoding); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CountGlyphs(ReadOnlySpan, SKTextEncoding) instead.")] public int CountGlyphs(ReadOnlySpan str, SKEncoding encoding) { return GetFont().CountGlyphs(str, encoding.ToTextEncoding()); } public int CountGlyphs(ReadOnlySpan str, SKTextEncoding encoding) { return GetFont().CountGlyphs(str, encoding); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use CountGlyphs(IntPtr, int, SKTextEncoding) instead.")] public int CountGlyphs(IntPtr str, int strLen, SKEncoding encoding) { return CountGlyphs(str, strLen, encoding.ToTextEncoding()); } public int CountGlyphs(IntPtr str, int strLen, SKTextEncoding encoding) { return GetFont().CountGlyphs(str, strLen * encoding.GetCharacterByteSize(), encoding); } public ushort GetGlyph(int codepoint) { return GetFont().GetGlyph(codepoint); } public ushort[] GetGlyphs(ReadOnlySpan codepoints) { return GetFont().GetGlyphs(codepoints); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(string) instead.")] public int GetGlyphs(string text, out ushort[] glyphs) { glyphs = GetGlyphs(text); return glyphs.Length; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(string) instead.")] public int GetGlyphs(string text, SKEncoding encoding, out ushort[] glyphs) { return GetGlyphs(text, out glyphs); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(byte[], SKTextEncoding) instead.")] public int GetGlyphs(byte[] text, SKEncoding encoding, out ushort[] glyphs) { return GetGlyphs(text.AsSpan(), encoding, out glyphs); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(ReadOnlySpan, SKTextEncoding) instead.")] public int GetGlyphs(ReadOnlySpan text, SKEncoding encoding, out ushort[] glyphs) { glyphs = GetGlyphs(text, encoding); return glyphs.Length; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(IntPtr, int, SKTextEncoding) instead.")] public int GetGlyphs(IntPtr text, int length, SKEncoding encoding, out ushort[] glyphs) { glyphs = GetGlyphs(text, length, encoding); return glyphs.Length; } public ushort[] GetGlyphs(string text) { return GetGlyphs(text.AsSpan()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(string) instead.")] public ushort[] GetGlyphs(string text, SKEncoding encoding) { return GetGlyphs(text.AsSpan()); } public ushort[] GetGlyphs(ReadOnlySpan text) { using SKFont sKFont = ToFont(); return sKFont.GetGlyphs(text); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(ReadOnlySpan, SKTextEncoding) instead.")] public ushort[] GetGlyphs(byte[] text, SKEncoding encoding) { return GetGlyphs(text.AsSpan(), encoding.ToTextEncoding()); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(ReadOnlySpan, SKTextEncoding) instead.")] public ushort[] GetGlyphs(ReadOnlySpan text, SKEncoding encoding) { return GetGlyphs(text, encoding.ToTextEncoding()); } public ushort[] GetGlyphs(ReadOnlySpan text, SKTextEncoding encoding) { using SKFont sKFont = ToFont(); return sKFont.GetGlyphs(text, encoding); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetGlyphs(IntPtr, int, SKTextEncoding) instead.")] public ushort[] GetGlyphs(IntPtr text, int length, SKEncoding encoding) { return GetGlyphs(text, length, encoding.ToTextEncoding()); } public ushort[] GetGlyphs(IntPtr text, int length, SKTextEncoding encoding) { using SKFont sKFont = ToFont(); return sKFont.GetGlyphs(text, length * encoding.GetCharacterByteSize(), encoding); } public bool ContainsGlyph(int codepoint) { return GetFont().ContainsGlyph(codepoint); } public bool ContainsGlyphs(ReadOnlySpan codepoints) { return GetFont().ContainsGlyphs(codepoints); } public bool ContainsGlyphs(string text) { return GetFont().ContainsGlyphs(text); } public bool ContainsGlyphs(ReadOnlySpan text) { return GetFont().ContainsGlyphs(text); } public bool ContainsGlyphs(ReadOnlySpan text, SKTextEncoding encoding) { return ContainsGlyphs(text, encoding); } public bool ContainsGlyphs(IntPtr text, int length, SKTextEncoding encoding) { return GetFont().ContainsGlyphs(text, length * encoding.GetCharacterByteSize(), encoding); } internal SKFont GetFont() { return font ?? (font = SKObject.OwnedBy(new SKFont(this), this)); } public SKFont ToFont() { return new SKFont(this); } public SKFont ToFont(float size, float scaleX = 1f, float skewX = 0f) { return new SKFont(this, size, scaleX, skewX); } public SKStreamAsset OpenStream() { int ttcIndex; return OpenStream(out ttcIndex); } public unsafe SKStreamAsset OpenStream(out int ttcIndex) { fixed (int* ttcIndex2 = &ttcIndex) { return SKStreamAsset.GetObject(SkiaApi.sk_typeface_open_stream(Handle, ttcIndex2)); } } public unsafe int[] GetKerningPairAdjustments(ReadOnlySpan glyphs) { int[] array = new int[glyphs.Length]; fixed (ushort* glyphs2 = glyphs) { fixed (int* adjustments = array) { SkiaApi.sk_typeface_get_kerning_pair_adjustments(Handle, glyphs2, glyphs.Length, adjustments); } } return array; } internal static SKTypeface GetObject(IntPtr handle) { return SKObject.GetOrAddObject(handle, (IntPtr h, bool o) => new SKTypeface(h, o)); } } public class SKVertices : SKObject, ISKNonVirtualReferenceCounted, ISKReferenceCounted, ISKSkipObjectRegistration { internal SKVertices(IntPtr x, bool owns) : base(x, owns) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } void ISKNonVirtualReferenceCounted.ReferenceNative() { SkiaApi.sk_vertices_ref(Handle); } void ISKNonVirtualReferenceCounted.UnreferenceNative() { SkiaApi.sk_vertices_unref(Handle); } public static SKVertices CreateCopy(SKVertexMode vmode, SKPoint[] positions, SKColor[] colors) { return CreateCopy(vmode, positions, null, colors, null); } public static SKVertices CreateCopy(SKVertexMode vmode, SKPoint[] positions, SKPoint[] texs, SKColor[] colors) { return CreateCopy(vmode, positions, texs, colors, null); } public unsafe static SKVertices CreateCopy(SKVertexMode vmode, SKPoint[] positions, SKPoint[] texs, SKColor[] colors, ushort[] indices) { if (positions == null) { throw new ArgumentNullException("positions"); } if (texs != null && positions.Length != texs.Length) { throw new ArgumentException("The number of texture coordinates must match the number of vertices.", "texs"); } if (colors != null && positions.Length != colors.Length) { throw new ArgumentException("The number of colors must match the number of vertices.", "colors"); } int vertexCount = positions.Length; int indexCount = ((indices != null) ? indices.Length : 0); fixed (SKPoint* positions2 = positions) { fixed (SKPoint* texs2 = texs) { fixed (SKColor* colors2 = colors) { fixed (ushort* indices2 = indices) { return GetObject(SkiaApi.sk_vertices_make_copy(vmode, vertexCount, positions2, texs2, (uint*)colors2, indexCount, indices2)); } } } } } internal static SKVertices GetObject(IntPtr handle) { if (!(handle == IntPtr.Zero)) { return new SKVertices(handle, owns: true); } return null; } } public abstract class SKXmlWriter : SKObject { internal SKXmlWriter(IntPtr h, bool owns) : base(h, owns) { } } public class SKXmlStreamWriter : SKXmlWriter { internal SKXmlStreamWriter(IntPtr h, bool owns) : base(h, owns) { } public SKXmlStreamWriter(SKWStream stream) : this(IntPtr.Zero, owns: true) { if (stream == null) { throw new ArgumentNullException("stream"); } Handle = SkiaApi.sk_xmlstreamwriter_new(stream.Handle); } protected override void Dispose(bool disposing) { base.Dispose(disposing); } protected override void DisposeNative() { SkiaApi.sk_xmlstreamwriter_delete(Handle); } } internal static class Utils { internal readonly ref struct RentedArray { public readonly T[] Array; public readonly Span Span; public int Length => Span.Length; public T this[int index] { get { return Span[index]; } set { Span[index] = value; } } internal RentedArray(int length) { Array = ArrayPool.Shared.Rent(length); Span = new Span(Array, 0, length); } [EditorBrowsable(EditorBrowsableState.Never)] public ref T GetPinnableReference() { return ref Span.GetPinnableReference(); } public void Dispose() { if (Array != null) { ArrayPool.Shared.Return(Array); } } public static explicit operator T[](RentedArray scope) { return scope.Array; } public static implicit operator Span(RentedArray scope) { return scope.Span; } public static implicit operator ReadOnlySpan(RentedArray scope) { return scope.Span; } } internal const float NearlyZero = 0.00024414062f; internal static int GetPreambleSize(SKData data) { if (data == null) { throw new ArgumentNullException("data"); } ReadOnlySpan readOnlySpan = data.AsSpan(); int length = readOnlySpan.Length; if (length >= 2 && readOnlySpan[0] == 254 && readOnlySpan[1] == byte.MaxValue) { return 2; } if (length >= 3 && readOnlySpan[0] == 239 && readOnlySpan[1] == 187 && readOnlySpan[2] == 191) { return 3; } if (length >= 3 && readOnlySpan[0] == 43 && readOnlySpan[1] == 47 && readOnlySpan[2] == 118) { return 3; } if (length >= 4 && readOnlySpan[0] == 0 && readOnlySpan[1] == 0 && readOnlySpan[2] == 254 && readOnlySpan[3] == byte.MaxValue) { return 4; } return 0; } internal unsafe static Span AsSpan(this IntPtr ptr, int size) { return new Span((void*)ptr, size); } internal unsafe static ReadOnlySpan AsReadOnlySpan(this IntPtr ptr, int size) { return new ReadOnlySpan((void*)ptr, size); } internal static bool NearlyEqual(float a, float b, float tolerance) { return Math.Abs(a - b) <= tolerance; } internal unsafe static byte[] GetBytes(this Encoding encoding, ReadOnlySpan text) { if (text.Length == 0) { return new byte[0]; } fixed (char* chars = text) { int byteCount = encoding.GetByteCount(chars, text.Length); if (byteCount == 0) { return new byte[0]; } byte[] array = new byte[byteCount]; fixed (byte* bytes = array) { encoding.GetBytes(chars, text.Length, bytes, byteCount); } return array; } } public static RentedArray RentArray(int length, bool nullIfEmpty = false) { if (!nullIfEmpty || length > 0) { return new RentedArray(length); } return default(RentedArray); } public static RentedArray RentHandlesArray(SKObject[] objects, bool nullIfEmpty = false) { RentedArray result = RentArray((objects != null) ? objects.Length : 0, nullIfEmpty); for (int i = 0; i < result.Length; i++) { result[i] = objects[i]?.Handle ?? IntPtr.Zero; } return result; } } public static class StringUtilities { internal const string NullTerminator = "\0"; private static int GetUnicodeStringLength(SKTextEncoding encoding) { return encoding switch { SKTextEncoding.Utf8 => 1, SKTextEncoding.Utf16 => 1, SKTextEncoding.Utf32 => 2, _ => throw new ArgumentOutOfRangeException("encoding", $"Encoding {encoding} is not supported."), }; } internal static int GetCharacterByteSize(this SKTextEncoding encoding) { return encoding switch { SKTextEncoding.Utf8 => 1, SKTextEncoding.Utf16 => 2, SKTextEncoding.Utf32 => 4, _ => throw new ArgumentOutOfRangeException("encoding", $"Encoding {encoding} is not supported."), }; } public static int GetUnicodeCharacterCode(string character, SKTextEncoding encoding) { if (character == null) { throw new ArgumentNullException("character"); } if (GetUnicodeStringLength(encoding) != character.Length) { throw new ArgumentException("character", "Only a single character can be specified."); } byte[] encodedText = GetEncodedText(character, encoding); return BitConverter.ToInt32(encodedText, 0); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use GetEncodedText(string, SKTextEncoding) instead.")] public static byte[] GetEncodedText(string text, SKEncoding encoding) { return GetEncodedText(text.AsSpan(), encoding.ToTextEncoding()); } public static byte[] GetEncodedText(string text, SKTextEncoding encoding) { return GetEncodedText(text.AsSpan(), encoding); } internal static byte[] GetEncodedText(string text, SKTextEncoding encoding, bool addNull) { if (!string.IsNullOrEmpty(text) && addNull) { text += "\0"; } return GetEncodedText(text.AsSpan(), encoding); } public static byte[] GetEncodedText(ReadOnlySpan text, SKTextEncoding encoding) { return encoding switch { SKTextEncoding.Utf8 => Encoding.UTF8.GetBytes(text), SKTextEncoding.Utf16 => Encoding.Unicode.GetBytes(text), SKTextEncoding.Utf32 => Encoding.UTF32.GetBytes(text), _ => throw new ArgumentOutOfRangeException("encoding", $"Encoding {encoding} is not supported."), }; } public static string GetString(IntPtr data, int dataLength, SKTextEncoding encoding) { return GetString(data.AsReadOnlySpan(dataLength), 0, dataLength, encoding); } public static string GetString(byte[] data, SKTextEncoding encoding) { return GetString(data, 0, data.Length, encoding); } public static string GetString(byte[] data, int index, int count, SKTextEncoding encoding) { if (data == null) { throw new ArgumentNullException("data"); } return encoding switch { SKTextEncoding.Utf8 => Encoding.UTF8.GetString(data, index, count), SKTextEncoding.Utf16 => Encoding.Unicode.GetString(data, index, count), SKTextEncoding.Utf32 => Encoding.UTF32.GetString(data, index, count), _ => throw new ArgumentOutOfRangeException("encoding", $"Encoding {encoding} is not supported."), }; } public static string GetString(ReadOnlySpan data, SKTextEncoding encoding) { return GetString(data, 0, data.Length, encoding); } public unsafe static string GetString(ReadOnlySpan data, int index, int count, SKTextEncoding encoding) { data = data.Slice(index, count); if (data.Length == 0) { return string.Empty; } fixed (byte* bytes = data) { return encoding switch { SKTextEncoding.Utf8 => Encoding.UTF8.GetString(bytes, data.Length), SKTextEncoding.Utf16 => Encoding.Unicode.GetString(bytes, data.Length), SKTextEncoding.Utf32 => Encoding.UTF32.GetString(bytes, data.Length), _ => throw new ArgumentOutOfRangeException("encoding", $"Encoding {encoding} is not supported."), }; } } } } namespace SkiaSharp.Internals { public static class PlatformConfiguration { private const string LibCLibrary = "libc"; private static string linuxFlavor; private static readonly Lazy isGlibcLazy; public static bool IsUnix { get; } public static bool IsWindows { get; } public static bool IsMac { get; } public static bool IsLinux { get; } public static bool IsArm { get; } public static bool Is64Bit { get; } public static string LinuxFlavor { get { if (!IsLinux) { return null; } if (!string.IsNullOrEmpty(linuxFlavor)) { return linuxFlavor; } if (!IsGlibc) { return "musl"; } return null; } set { linuxFlavor = value; } } public static bool IsGlibc { get { if (IsLinux) { return isGlibcLazy.Value; } return false; } } static PlatformConfiguration() { isGlibcLazy = new Lazy(IsGlibcImplementation); IsMac = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); IsUnix = IsMac || IsLinux; IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); Architecture processArchitecture = RuntimeInformation.ProcessArchitecture; IsArm = processArchitecture == Architecture.Arm || processArchitecture == Architecture.Arm64; Is64Bit = IntPtr.Size == 8; } private static bool IsGlibcImplementation() { try { gnu_get_libc_version(); return true; } catch (TypeLoadException) { return false; } } [DllImport("libc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] private static extern IntPtr gnu_get_libc_version(); } public interface IPlatformLock { void EnterReadLock(); void ExitReadLock(); void EnterWriteLock(); void ExitWriteLock(); void EnterUpgradeableReadLock(); void ExitUpgradeableReadLock(); } public static class PlatformLock { private class ReadWriteLock : IPlatformLock { private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); public void EnterReadLock() { _lock.EnterReadLock(); } public void ExitReadLock() { _lock.ExitReadLock(); } public void EnterWriteLock() { _lock.EnterWriteLock(); } public void ExitWriteLock() { _lock.ExitWriteLock(); } public void EnterUpgradeableReadLock() { _lock.EnterUpgradeableReadLock(); } public void ExitUpgradeableReadLock() { _lock.ExitUpgradeableReadLock(); } } private class NonAlertableWin32Lock : IPlatformLock { public struct CRITICAL_SECTION { public IntPtr DebugInfo; public int LockCount; public int RecursionCount; public IntPtr OwningThread; public IntPtr LockSemaphore; public UIntPtr SpinCount; } private IntPtr _cs; public NonAlertableWin32Lock() { _cs = Marshal.AllocHGlobal(Marshal.SizeOf()); if (_cs == IntPtr.Zero) { throw new OutOfMemoryException("Failed to allocate memory for critical section"); } InitializeCriticalSectionEx(_cs, 4000u, 0u); } ~NonAlertableWin32Lock() { if (_cs != IntPtr.Zero) { DeleteCriticalSection(_cs); Marshal.FreeHGlobal(_cs); _cs = IntPtr.Zero; } } private void Enter() { if (_cs != IntPtr.Zero) { EnterCriticalSection(_cs); } } private void Leave() { if (_cs != IntPtr.Zero) { LeaveCriticalSection(_cs); } } public void EnterReadLock() { Enter(); } public void ExitReadLock() { Leave(); } public void EnterWriteLock() { Enter(); } public void ExitWriteLock() { Leave(); } public void EnterUpgradeableReadLock() { Enter(); } public void ExitUpgradeableReadLock() { Leave(); } [DllImport("Kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool InitializeCriticalSectionEx(IntPtr lpCriticalSection, uint dwSpinCount, uint Flags); [DllImport("Kernel32.dll")] private static extern void DeleteCriticalSection(IntPtr lpCriticalSection); [DllImport("Kernel32.dll")] private static extern void EnterCriticalSection(IntPtr lpCriticalSection); [DllImport("Kernel32.dll")] private static extern void LeaveCriticalSection(IntPtr lpCriticalSection); } public static Func Factory { get; set; } = DefaultFactory; public static IPlatformLock Create() { return Factory(); } public static IPlatformLock DefaultFactory() { if (PlatformConfiguration.IsWindows) { return new NonAlertableWin32Lock(); } return new ReadWriteLock(); } } }