From 73dca089342be79431f9717f8e203ddd6cf3a82a Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 14 Aug 2025 13:35:09 +0200 Subject: [PATCH 1/7] [CoreGraphics] Update to Xcode 26 beta 1-5. TODOS TODOS: * Review AI code. * Verify no FIXME/TODOs. --- src/CoreGraphics/CGBitmapContext.cs | 170 ++++++++++++++++++ src/CoreGraphics/CGBitmapInfo.cs | 38 ++++ src/CoreGraphics/CGBitmapParameters.cs | 112 ++++++++++++ src/CoreGraphics/CGColor.cs | 42 +++++ src/CoreGraphics/CGContentInfo.cs | 62 +++++++ src/CoreGraphics/CGContentToneMappingInfo.cs | 43 +++++ src/CoreGraphics/CGGradient.cs | 62 +++++++ src/CoreGraphics/CGImage.cs | 98 ++++++++++ src/CoreGraphics/CGRenderingBufferProvider.cs | 141 +++++++++++++++ src/CoreGraphics/CGShading.cs | 151 +++++++++++++--- src/CoreGraphics/CGToneMappingOptions.cs | 31 ++++ src/DotNetGlobals.cs | 4 + src/ObjCRuntime/Runtime.cs | 28 +++ src/corefoundation.cs | 7 + src/coregraphics.cs | 105 +++++++++++ src/frameworks.sources | 6 + .../Documentation.KnownFailures.txt | 61 ++++++- tests/introspection/ApiCMAttachmentTest.cs | 1 + .../CoreGraphics/BitmapContextTest.cs | 166 +++++++++++++++++ .../CoreGraphics/CGBitmapInfoTest.cs | 20 +++ .../CoreGraphics/CGBitmapParametersTest.cs | 82 +++++++++ .../CoreGraphics/CGContentInfoTest.cs | 58 ++++++ .../CGContentToneMappingInfoTest.cs | 77 ++++++++ .../CoreGraphics/CGImageTest.cs | 16 ++ .../CGRenderingBufferProviderTest.cs | 58 ++++++ .../CoreGraphics/CGToneMappingOptionsTest.cs | 27 +++ .../monotouch-test/CoreGraphics/ColorTest.cs | 19 ++ .../CoreGraphics/FunctionTest.cs | 43 +++-- .../CoreGraphics/GradientTest.cs | 28 +++ .../CoreGraphics/ShadingTest.cs | 83 +++++++++ tests/monotouch-test/GlobalUsings.cs | 6 + .../MacCatalyst-CoreGraphics.todo | 34 ---- .../common-CoreFoundation.ignore | 5 +- .../common-CoreGraphics.ignore | 1 - .../iOS-CoreGraphics.todo | 34 ---- .../macOS-CoreGraphics.todo | 34 ---- .../tvOS-CoreGraphics.todo | 34 ---- 37 files changed, 1810 insertions(+), 177 deletions(-) create mode 100644 src/CoreGraphics/CGBitmapInfo.cs create mode 100644 src/CoreGraphics/CGBitmapParameters.cs create mode 100644 src/CoreGraphics/CGContentInfo.cs create mode 100644 src/CoreGraphics/CGContentToneMappingInfo.cs create mode 100644 src/CoreGraphics/CGRenderingBufferProvider.cs create mode 100644 src/CoreGraphics/CGToneMappingOptions.cs create mode 100644 tests/monotouch-test/CoreGraphics/CGBitmapInfoTest.cs create mode 100644 tests/monotouch-test/CoreGraphics/CGBitmapParametersTest.cs create mode 100644 tests/monotouch-test/CoreGraphics/CGContentInfoTest.cs create mode 100644 tests/monotouch-test/CoreGraphics/CGContentToneMappingInfoTest.cs create mode 100644 tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs create mode 100644 tests/monotouch-test/CoreGraphics/CGToneMappingOptionsTest.cs create mode 100644 tests/monotouch-test/CoreGraphics/ShadingTest.cs create mode 100644 tests/monotouch-test/GlobalUsings.cs delete mode 100644 tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-CoreGraphics.todo delete mode 100644 tests/xtro-sharpie/api-annotations-dotnet/iOS-CoreGraphics.todo delete mode 100644 tests/xtro-sharpie/api-annotations-dotnet/macOS-CoreGraphics.todo delete mode 100644 tests/xtro-sharpie/api-annotations-dotnet/tvOS-CoreGraphics.todo diff --git a/src/CoreGraphics/CGBitmapContext.cs b/src/CoreGraphics/CGBitmapContext.cs index 33e22f98a2e7..f7f5d19274c6 100644 --- a/src/CoreGraphics/CGBitmapContext.cs +++ b/src/CoreGraphics/CGBitmapContext.cs @@ -29,6 +29,7 @@ #nullable enable using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; @@ -225,6 +226,175 @@ public CGBitmapFlags BitmapInfo { // do not return an invalid instance (null handle) if something went wrong return h == IntPtr.Zero ? null : new CGImage (h, true); } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern unsafe IntPtr /* CGContextRef */ CGBitmapContextCreateAdaptive ( + nuint /* size_t */ width, + nuint /* size_t */ height, + IntPtr /* CFDictionaryRef __nullable */ auxiliaryInfo, + BlockLiteral* /* (^__nullable onResolve)(const CGContentInfo* __nonnull, CGBitmapParameters* __nonnull) */ onResolve, + BlockLiteral* /* (^__nullable onAllocate)(const CGContentInfo* __nonnull, const CGBitmapParameters* __nonnull) */ onAllocate, + BlockLiteral* /* (^__nullable onFree)(CGRenderingBufferProviderRef __nonnull, const CGContentInfo* __nonnull, const CGBitmapParameters* __nonnull) */ onFree, + BlockLiteral* /* (^__nullable onError)(CFErrorRef __nonnull, const CGContentInfo* __nonnull, const CGBitmapParameters* __nonnull) */ onError + ); + + /// Create a bitmap context designed to choose the optimal bit depth, colorspace and EDR target headroom. + /// The width of the new . + /// The height of the new . + /// Any additional information for the creation of the new . + /// A callback to modify the used to create the new . + /// A callback to allocate memory for the new . + /// A callback to free any allocated memory for the new . + /// A callback that is called in case of any errors. + /// A new if successful, otherwise. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [BindingImpl (BindingImplOptions.Optimizable)] + public unsafe static CGBitmapContext? Create (nuint width, nuint height, NSDictionary? auxiliaryInfo, OnResolveCallback? onResolve, OnAllocateCallback? onAllocate, OnFreeCallback? onFree, OnErrorCallback? onError) + { + delegate* unmanaged onResolveTrampoline = &CGBitmapContextCreateAdaptive_OnResolve; + using var onResolveBlock = onResolve is null ? default (BlockLiteral) : new BlockLiteral (onResolveTrampoline, onResolve, typeof (CGBitmapContext), nameof (CGBitmapContextCreateAdaptive_OnResolve)); + + delegate* unmanaged onAllocateTrampoline = &CGBitmapContextCreateAdaptive_OnAllocate; + using var onAllocateBlock = onAllocate is null ? default (BlockLiteral) : new BlockLiteral (onAllocateTrampoline, onAllocate, typeof (CGBitmapContext), nameof (CGBitmapContextCreateAdaptive_OnAllocate)); + + delegate* unmanaged onFreeTrampoline = &CGBitmapContextCreateAdaptive_OnFree; + using var onFreeBlock = onFree is null ? default (BlockLiteral) : new BlockLiteral (onFreeTrampoline, onFree, typeof (CGBitmapContext), nameof (CGBitmapContextCreateAdaptive_OnFree)); + + delegate* unmanaged onErrorTrampoline = &CGBitmapContextCreateAdaptive_OnError; + using var onErrorBlock = onError is null ? default (BlockLiteral) : new BlockLiteral (onErrorTrampoline, onError, typeof (CGBitmapContext), nameof (CGBitmapContextCreateAdaptive_OnError)); + + var rv = CGBitmapContextCreateAdaptive ( + width, height, + auxiliaryInfo.GetHandle (), + onResolve is null ? null : &onResolveBlock, + onAllocate is null ? null : &onAllocateBlock, + onFree is null ? null : &onFreeBlock, + onError is null ? null : &onErrorBlock + ); + + GC.KeepAlive (auxiliaryInfo); + + if (rv == IntPtr.Zero) + return null; + + return new CGBitmapContext (rv, true); + } + + /// Create a bitmap context designed to choose the optimal bit depth, colorspace and EDR target headroom. + /// The width of the new . + /// The height of the new . + /// Any additional information for the creation of the new . + /// A callback to modify the used to create the new . + /// A callback to allocate memory for the new . + /// A callback to free any allocated memory for the new . + /// A callback that is called in case of any errors. + /// A new if successful, otherwise. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public unsafe static CGBitmapContext? Create (nuint width, nuint height, CGAdaptiveOptions? auxiliaryInfo, OnResolveCallback? onResolve, OnAllocateCallback? onAllocate, OnFreeCallback? onFree, OnErrorCallback? onError) + { + return Create (width, height, auxiliaryInfo?.Dictionary, onResolve, onAllocate, onFree, onError); + } + + public delegate bool OnResolveCallback (ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters); + + [UnmanagedCallersOnly] + unsafe static byte CGBitmapContextCreateAdaptive_OnResolve (IntPtr block, CGContentInfo* contentInfo, CGBitmapParameters* bitmapParameters) + { + var del = BlockLiteral.GetTarget (block); + if (del is not null) { + var rv = del (ref Unsafe.AsRef (contentInfo), ref Unsafe.AsRef (bitmapParameters)); + return rv.AsByte (); + } + return 0; + } + + public delegate CGRenderingBufferProvider /* CGRenderingBufferProviderRef */ OnAllocateCallback (ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters); + + [UnmanagedCallersOnly] + unsafe static IntPtr CGBitmapContextCreateAdaptive_OnAllocate (IntPtr block, CGContentInfo* contentInfo, CGBitmapParameters* bitmapParameters) + { + var del = BlockLiteral.GetTarget (block); + if (del is not null) { + var rv = del (ref Unsafe.AsRef (contentInfo), ref Unsafe.AsRef (bitmapParameters)); + return Runtime.RetainAndAutoreleaseHandle (rv); + } + return IntPtr.Zero; + } + + public delegate void OnFreeCallback (CGRenderingBufferProvider /* CGRenderingBufferProviderRef */ renderingBufferProvider, ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters); + + [UnmanagedCallersOnly] + unsafe static void CGBitmapContextCreateAdaptive_OnFree (IntPtr block, IntPtr /* CGRenderingBufferProviderRef */ bufferingProviderRef, CGContentInfo* contentInfo, CGBitmapParameters* bitmapParameters) + { + var del = BlockLiteral.GetTarget (block); + if (del is not null) { + using var renderingBufferProvider = new CGRenderingBufferProvider (bufferingProviderRef, false); + del (renderingBufferProvider, ref Unsafe.AsRef (contentInfo), ref Unsafe.AsRef (bitmapParameters)); + } + } + + public delegate void OnErrorCallback (NSError error, ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters); + + [UnmanagedCallersOnly] + unsafe static void CGBitmapContextCreateAdaptive_OnError (IntPtr block, IntPtr errorHandle, CGContentInfo* contentInfo, CGBitmapParameters* bitmapParameters) + { + var del = BlockLiteral.GetTarget (block); + if (del is not null) { + var error = Runtime.GetNSObject (errorHandle, false)!; + del (error, ref Unsafe.AsRef (contentInfo), ref Unsafe.AsRef (bitmapParameters)); + } + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern CGContentToneMappingInfo CGContextGetContentToneMappingInfo (IntPtr /* CGContextRef __nonnull */ context); + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern void CGContextSetContentToneMappingInfo (IntPtr /* CGContextRef __nonnull */ context, CGContentToneMappingInfo info); + + /// Get or set the content tone mapping info. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public CGContentToneMappingInfo ContentToneMappingInfo { + get => CGContextGetContentToneMappingInfo (GetCheckedHandle ()); + set => CGContextSetContentToneMappingInfo (GetCheckedHandle (), value); + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern void CGContextSynchronizeAttributes (IntPtr /* CGContextRef */ context); + + /// Synchronize destination attributes. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public void SynchronizeAttributes () + { + CGContextSynchronizeAttributes (GetCheckedHandle ()); + } #endif // !COREBUILD } } diff --git a/src/CoreGraphics/CGBitmapInfo.cs b/src/CoreGraphics/CGBitmapInfo.cs new file mode 100644 index 000000000000..bca65d82abc6 --- /dev/null +++ b/src/CoreGraphics/CGBitmapInfo.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace CoreGraphics { + public static class CGBitmapInfoExtensions { + /// Get the alpha info flags for this value. + /// The value with the flags to get. + /// The alpha info flags for this value. + public static CGImageAlphaInfo GetAlphaInfo (this CGBitmapInfo value) + { + return (CGImageAlphaInfo) (value & CGBitmapInfo.AlphaInfoMask); + } + + /// Get the component info flags for this value. + /// The value with the flags to get. + /// The component info flags for this value. + public static CGImageComponentInfo GetComponentInfo (this CGBitmapInfo value) + { + return (CGImageComponentInfo) (value & CGBitmapInfo.ComponentInfoMask); + } + + /// Get the byte order info flags for this value. + /// The value with the flags to get. + /// The byte order info flags for this value. + public static CGImageByteOrderInfo GetByteOrderInfo (this CGBitmapInfo value) + { + return (CGImageByteOrderInfo) (value & CGBitmapInfo.ByteOrderInfoMask); + } + + /// Get the pixel format info flags for this value. + /// The value with the flags to get. + /// The pixel formatinfo flags for this value. + public static CGImagePixelFormatInfo GetPixelFormatInfo (this CGBitmapInfo value) + { + return (CGImagePixelFormatInfo) (value & CGBitmapInfo.PixelFormatInfoMask); + } + } +} diff --git a/src/CoreGraphics/CGBitmapParameters.cs b/src/CoreGraphics/CGBitmapParameters.cs new file mode 100644 index 000000000000..b849c636fdc6 --- /dev/null +++ b/src/CoreGraphics/CGBitmapParameters.cs @@ -0,0 +1,112 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +using CoreFoundation; + +namespace CoreGraphics { + /// This struct contains values used when creating an adaptive bitmap context. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [SupportedOSPlatform ("tvos26.0")] + [StructLayout (LayoutKind.Sequential)] + public struct CGBitmapParameters { + nuint width; + nuint height; + nuint bytesPerPixel; + nuint alignedBytesPerRow; /* Rounded up to an appropriate value for bitmap data */ + CGComponent component; + CGBitmapLayout layout; + CGImagePixelFormatInfo format; + IntPtr /* CGColorSpaceRef */ colorSpace; + byte /* bool */ hasPremultipliedAlpha; + nint /* CFByteOrder */ byteOrder; + float edrTargetHeadroom; + + /// The width of the new . + public nuint Width { + get => width; + set => width = value; + } + + /// The height of the new . + public nuint Height { + get => height; + set => height = value; + } + + /// The number of bytes per pixel for the new . + public nuint BytesPerPixel { + get => bytesPerPixel; + set => bytesPerPixel = value; + } + + /// The number of aligned bytes per row for the new . + public nuint AlignedBytesPerRow { + get => alignedBytesPerRow; + set => alignedBytesPerRow = value; + } + + /// The value for the new . + public CGComponent Component { + get => component; + set => component = value; + } + + /// The value for the new . + public CGBitmapLayout Layout { + get => layout; + set => layout = value; + } + + /// The pixel format for the new . + public CGImagePixelFormatInfo Format { + get => format; + set => format = value; + } + + /// The handle for the colorspace of the new . + public IntPtr ColorSpaceHandle { + get => colorSpace; + set => colorSpace = value; + } + + /// The for the new . + /// When setting this value, the calling code must keep a reference to the instance, because this struct does not increment the retainCount of it to prevent the GC from collecting the instance. + public CGColorSpace? ColorSpace { + get => Runtime.GetINativeObject (colorSpace, false); + set { + // this is unsafe: the calling code must keep the managed CGColorSpace insatnce around somehow. +#pragma warning disable RBI0014 + colorSpace = value!.GetNonNullHandle (nameof (value)); +#pragma warning restore RBI0014 + } + } + + /// Whether the new has premultiplied alpha values. + public bool HasPremultipliedAlpha { + get => hasPremultipliedAlpha != 0; + set => hasPremultipliedAlpha = value.AsByte (); + } + + /// The byte order for the new . + public CFByteOrder ByteOrder { + get => (CFByteOrder) byteOrder; + set => byteOrder = (nint) (long) value; + } + + /// The EDR target headroom for the new . + public float EdrTargetHeadroom { + get => edrTargetHeadroom; + set => edrTargetHeadroom = value; + } + + /// Returns a string representation of this . + public override string ToString () + { + return $"CGBitmapParameters[Width={Width};Height={Height};BytesPerPixel={BytesPerPixel};AlignedBytesPerRow={AlignedBytesPerRow};Component={Component};Layout={Layout};Format={Format};ColorSpaceHandle={ColorSpaceHandle};ColorSpace={ColorSpace};HasPremultipliedAlpha={HasPremultipliedAlpha};ByteOrder={ByteOrder};EdrTargetHeadroom={EdrTargetHeadroom}]"; + } + } +} diff --git a/src/CoreGraphics/CGColor.cs b/src/CoreGraphics/CGColor.cs index fe41e8c784e4..fe859b83a3ce 100644 --- a/src/CoreGraphics/CGColor.cs +++ b/src/CoreGraphics/CGColor.cs @@ -412,6 +412,48 @@ public CGPattern? Pattern { [SupportedOSPlatform ("maccatalyst")] public string? AXName => CFString.FromHandle (AXNameFromColor (Handle)); + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern IntPtr /* CGColorRef gc_nullable */ CGColorCreateWithContentHeadroom (float headroom, IntPtr /* CGColorSpaceRef gc_nullable */ space, nfloat red, nfloat green, nfloat blue, nfloat alpha); + + /// Create a with the specified content headroom, colorspace and color and alpha values. + /// The content headroom for the new . + /// The colorspace for the new . + /// The red color value for the new . + /// The green color value for the new . + /// The blue color value for the new . + /// The alpha value for the new . + /// A new instance if successful, otherwise. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public static CGColor? CreateWithContentHeadroom (float headroom, CGColorSpace? colorSpace, nfloat red, nfloat green, nfloat blue, nfloat alpha) + { + var h = CGColorCreateWithContentHeadroom (headroom, colorSpace.GetHandle (), red, green, blue, alpha); + GC.KeepAlive (colorSpace); + return h == IntPtr.Zero ? null : new CGColor (h, owns: true); + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern float CGColorGetContentHeadroom (IntPtr /* CGColorRef cg_nullable */ color); + + /// Get the content headroom for the color. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public float ContentHeadroom { + get => CGColorGetContentHeadroom (GetCheckedHandle ()); + } + #endif // !COREBUILD } diff --git a/src/CoreGraphics/CGContentInfo.cs b/src/CoreGraphics/CGContentInfo.cs new file mode 100644 index 000000000000..9239ccda8875 --- /dev/null +++ b/src/CoreGraphics/CGContentInfo.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +using System; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +using ObjCRuntime; + +namespace CoreGraphics { + /// This struct contains values used when creating an adaptive bitmap context. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [SupportedOSPlatform ("tvos26.0")] + [StructLayout (LayoutKind.Sequential)] + public struct CGContentInfo { + CGComponent deepestImageComponent; /* deepest image component */ + CGColorModel contentColorModels; /* sum of all color models drawn */ + byte /* bool */ hasWideGamut; /* there is content in wide gamut color space */ + byte /* bool */ hasTransparency; /* there is transparent content */ + float largestContentHeadroom; + + /// The deepest image component. + public CGComponent DeepestImageComponent { + get => deepestImageComponent; + set => deepestImageComponent = value; + } + + /// The sum of all drawn color models. + public CGColorModel ContentColorModels { + get => contentColorModels; + set => contentColorModels = value; + } + + /// Whether there's content in the wide gamut colorspace or not. + public bool HasWideGamut { + get => hasWideGamut != 0; + set => hasWideGamut = value.AsByte (); + } + + /// Whether there's transparent content or not. + public bool HasTransparency { + get => hasTransparency != 0; + set => hasTransparency = value.AsByte (); + } + + /// The largest content headroom value. + public float LargestContentHeadroom { + get => largestContentHeadroom; + set => largestContentHeadroom = value; + } + + /// Returns a string representation of this . + public override string ToString () + { + return $"CGContentInfo [DeepestImageComponent={DeepestImageComponent};ContentColorModels={ContentColorModels};HasWideGamut={HasWideGamut};HasTransparency={HasTransparency};LargestContentHeadroom={LargestContentHeadroom}]"; + } + } +} diff --git a/src/CoreGraphics/CGContentToneMappingInfo.cs b/src/CoreGraphics/CGContentToneMappingInfo.cs new file mode 100644 index 000000000000..907887ccf13b --- /dev/null +++ b/src/CoreGraphics/CGContentToneMappingInfo.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using ObjCRuntime; + +namespace CoreGraphics { + /// A struct that defines tone mapping information. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [StructLayout (LayoutKind.Sequential)] + public struct CGContentToneMappingInfo + { + CGToneMapping method; + IntPtr /* CFDictionaryRef __nullable */ options; + + /// The tone mapping method to use. + public CGToneMapping Method { + get => method; + set => method = value; + } + + /// Any tone-mapping options. + public NSDictionary? Options { + get => Runtime.GetNSObject (options); + set => options = Runtime.RetainAndAutoreleaseNSObject (value); + } + + /// Strongly typed tone-mapping options. + public CGToneMappingOptions? ToneMappingOptions { + get { + var dict = Options; + if (dict is null) + return null; + return new CGToneMappingOptions (dict); + } + set { + Options = value.GetDictionary (); + } + } + } +} diff --git a/src/CoreGraphics/CGGradient.cs b/src/CoreGraphics/CGGradient.cs index 1d27a6a35240..85196286e870 100644 --- a/src/CoreGraphics/CGGradient.cs +++ b/src/CoreGraphics/CGGradient.cs @@ -200,6 +200,68 @@ public CGGradient (CGColorSpace? colorspace, CGColor [] colors) : base (Create (colorspace, colors), true) { } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + unsafe static extern IntPtr /* CGGradientRef __nullable */ CGGradientCreateWithContentHeadroom ( + float headroom, + IntPtr /* CGColorSpaceRef cg_nullable */ space, + nfloat* /* const CGFloat * cg_nullable */ components, + nfloat* /* const CGFloat * cg_nullable */ locations, + nint count); + + /// Create a with the specified content headroom. + /// The content headroom for the new . + /// The colorspace to use for the gradient. This colorspace must support HDR. + /// The color components to map into the new . + /// An array of values that determines where, in the range from 0.0 to 1.0, should each color be located in the new . + /// A new if successful, otherwise. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public static CGGradient? Create (float headroom, CGColorSpace? colorSpace, nfloat[]? components, nfloat[]? locations) + { + // "The number of locations is specified by `count'" + // "The number of color components is the product of `count' and the number of color components of `space'." + var locationLength = locations?.Length ?? 0; + var colorComponentsCount = colorSpace?.Components ?? 0; + var expectedColorComponents = (locations?.Length ?? 0) * (colorSpace?.Components ?? 0); + if (expectedColorComponents > 0 && (components is null || components.Length < expectedColorComponents)) + throw new ArgumentException (nameof (components), string.Format ("Must have at least {0} color components when the {1} array has {2} and the color space {3} has {4} color components.", expectedColorComponents, nameof (locations), locationLength, nameof (colorSpace), colorComponentsCount)); + + unsafe { + fixed (nfloat* componentsPtr = components) { + fixed (nfloat* locationsPtr = locations) { + var result = CGGradientCreateWithContentHeadroom (headroom, colorSpace.GetHandle (), componentsPtr, locationsPtr, locationLength); + GC.KeepAlive (colorSpace); + if (result == IntPtr.Zero) + return null; + return new CGGradient (result, true); + } + } + } + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern float CGGradientGetContentHeadroom (IntPtr /* CGGradientRef gc_nullable */ gradient); + + /// Get the content headroom for this gradient. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public float ContentHeadroom { + get => CGGradientGetContentHeadroom (GetCheckedHandle ()); + } + #endif // !COREBUILD } } diff --git a/src/CoreGraphics/CGImage.cs b/src/CoreGraphics/CGImage.cs index 618f54dfa6b4..c616cbb7a260 100644 --- a/src/CoreGraphics/CGImage.cs +++ b/src/CoreGraphics/CGImage.cs @@ -125,6 +125,14 @@ public enum CGImagePixelFormatInfo : uint { /// To be added. RgbCif10 = 4 << 16, /// To be added. + [SupportedOSPlatform ("ios")] + [SupportedOSPlatform ("tvos")] + [SupportedOSPlatform ("macos")] + [SupportedOSPlatform ("maccatalyst")] + [ObsoletedOSPlatform ("ios26.0", "Use 'CGBitmapInfo.ByteOrderInfoMask' instead.")] + [ObsoletedOSPlatform ("macos26.0", "Use 'CGBitmapInfo.ByteOrderInfoMask' instead.")] + [ObsoletedOSPlatform ("tvos26.0", "Use 'CGBitmapInfo.ByteOrderInfoMask' instead.")] + [ObsoletedOSPlatform ("maccatalyst26.0", "Use 'CGBitmapInfo.ByteOrderInfoMask' instead.")] Mask = 0xF0000, } @@ -877,6 +885,96 @@ public static float DefaultHdrImageContentHeadroom { [SupportedOSPlatform ("macos15.0")] [SupportedOSPlatform ("tvos18.0")] public bool ContainsImageSpecificToneMappingMetadata => CGImageContainsImageSpecificToneMappingMetadata (Handle) != 0; + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern float CGImageCalculateContentHeadroom (IntPtr /* CGImageRef cg_nullable */ image); + + /// Get the calculated the content headroom. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public float CalculatedContentHeadroom { + get => CGImageCalculateContentHeadroom (this.GetHandle ()); + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern float CGImageGetContentAverageLightLevel (IntPtr /* CGImageRef cg_nullable */ image); + + /// Get the content average light level. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public float ContentAverageLightLevel { + get => CGImageGetContentAverageLightLevel (this.GetHandle ()); + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern float CGImageCalculateContentAverageLightLevel (IntPtr /* CGImageRef cg_nullable */ image); + + /// Get the calculated content average light level. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public float CalculatedContentAverageLightLevel { + get => CGImageCalculateContentAverageLightLevel (this.GetHandle ()); + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern IntPtr /* CGImageRef cg_nullable */ CGImageCreateCopyWithContentAverageLightLevel (IntPtr /* CGImageRef cg_nullable */ image, float averageLightLevel); + + /// Create a copy of this image, adding or replacing the content average light level. + /// A new instance of successful, otherwise. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public CGImage? CopyWithContentAverageLightLevel (float contentAverageLightLevel) + { + var h = CGImageCreateCopyWithContentAverageLightLevel (this.GetHandle (), contentAverageLightLevel); + if (h == IntPtr.Zero) + return null; + return new CGImage (h, true); + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern IntPtr /* CGImageRef cg_nullable */ CGImageCreateCopyWithCalculatedHDRStats (IntPtr /* CGImageRef cg_nullable */ image); + + /// Create a copy of this image, adding or replacing the calculated HDR stats. + /// A new instance of successful, otherwise. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public CGImage? CopyWithCalculatedHdrStats () + { + var h = CGImageCreateCopyWithCalculatedHDRStats (this.GetHandle ()); + if (h == IntPtr.Zero) + return null; + return new CGImage (h, true); + } #endif // !COREBUILD } } diff --git a/src/CoreGraphics/CGRenderingBufferProvider.cs b/src/CoreGraphics/CGRenderingBufferProvider.cs new file mode 100644 index 000000000000..ad647e684c9f --- /dev/null +++ b/src/CoreGraphics/CGRenderingBufferProvider.cs @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using CoreFoundation; + +namespace CoreGraphics { + // typedef struct CF_BRIDGED_TYPE(id) CGRenderingBufferProvider* CGRenderingBufferProviderRef; + /// This struct is used when creating adaptive bitmap contexts. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public class CGRenderingBufferProvider : NativeObject { + [Preserve (Conditional = true)] + internal CGRenderingBufferProvider (NativeHandle handle, bool owns) + : base (handle, owns) + { + } +#if !COREBUILD + [DllImport (Constants.CoreGraphicsLibrary)] + unsafe static extern IntPtr /* CGRenderingBufferProviderRef __nullable */ CGRenderingBufferProviderCreate ( + IntPtr /* void *__nullable */ info, + nuint size, + /* void* __nullable(^__nonnull lockPointer)(void* __nullable info) */ BlockLiteral* lockPointer, + /* void (^__nullable unlockPointer)(void* __nullable info, void* __nonnull pointer) */ BlockLiteral* unlockPointer, + /* void (^__nullable releaseInfo)(void* __nullable info) */ BlockLiteral* releaseInfo); + + /// Create a new instance. + /// A user-defined value that is passed to the callbacks. + /// The size of the buffer to create. + /// A callback that is called to lock the pointer. + /// A callback that is called to unlock the pointer. + /// A callback that is called to release when the is destroyed. + /// A new instance if successful, otherwise. + [BindingImpl (BindingImplOptions.Optimizable)] + public unsafe static CGRenderingBufferProvider? Create (IntPtr info, nuint size, LockPointerCallback lockPointer, UnlockPointerCallback unlockPointer, ReleaseInfoCallback releaseInfo) + { + if (lockPointer is null) + ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (lockPointer)); + + delegate* unmanaged lockPointerTrampoline = &LockPointerBlock; + using var lockPointerBlock = new BlockLiteral (lockPointerTrampoline, lockPointer, typeof (CGRenderingBufferProvider), nameof (LockPointerBlock)); + + delegate* unmanaged unlockPointerTrampoline = &UnlockPointerBlock; + using var unlockPointerBlock = unlockPointer is null ? default (BlockLiteral) : new BlockLiteral (unlockPointerTrampoline, unlockPointer, typeof (CGRenderingBufferProvider), nameof (UnlockPointerBlock)); + + delegate* unmanaged releaseInfoTrampoline = &ReleaseInfoBlock; + using var releaseInfoBlock = releaseInfo is null ? default (BlockLiteral) : new BlockLiteral (releaseInfoTrampoline, releaseInfo, typeof (CGRenderingBufferProvider), nameof (ReleaseInfoBlock)); + + var h = CGRenderingBufferProviderCreate ( + info, + size, + &lockPointerBlock, + unlockPointer is null ? null : &unlockPointerBlock, + releaseInfo is null ? null : &releaseInfoBlock); + if (h == IntPtr.Zero) + return null; + return new CGRenderingBufferProvider (h, true); + } + + public delegate IntPtr LockPointerCallback (IntPtr info); + + [UnmanagedCallersOnly] + unsafe static IntPtr LockPointerBlock (BlockLiteral *block, IntPtr info) + { + var del = BlockLiteral.GetTarget ((IntPtr) block); + if (del is not null) + return del (info); + return IntPtr.Zero; + } + + public delegate void UnlockPointerCallback (IntPtr info, IntPtr pointer); + + [UnmanagedCallersOnly] + unsafe static void UnlockPointerBlock (BlockLiteral *block, IntPtr info, IntPtr pointer) + { + var del = BlockLiteral.GetTarget ((IntPtr) block); + if (del is not null) + del (info, pointer); + } + + public delegate void ReleaseInfoCallback (IntPtr info); + + [UnmanagedCallersOnly] + unsafe static void ReleaseInfoBlock (BlockLiteral *block, IntPtr info) + { + var del = BlockLiteral.GetTarget ((IntPtr) block); + if (del is not null) + del (info); + } + + [DllImport (Constants.CoreGraphicsLibrary)] + static extern IntPtr /* CGRenderingBufferProviderRef __nullable */ CGRenderingBufferProviderCreateWithCFData (IntPtr /* CFMutableDataRef */ data); + + /// Create a new instance for a given instance. + /// The data to use when creawting the new instance. + /// A new instance if successful, otherwise. + public static CGRenderingBufferProvider? Create (NSData data) + { + var h = CGRenderingBufferProviderCreateWithCFData (data.GetNonNullHandle (nameof (data))); + GC.KeepAlive (data); + if (h == IntPtr.Zero) + return null; + return new CGRenderingBufferProvider (h, true); + } + + [DllImport (Constants.CoreGraphicsLibrary)] + static extern nuint CGRenderingBufferProviderGetSize (IntPtr /* CGRenderingBufferProviderRef */ provider); + + /// Get the size of this . + public nuint Size { + get => CGRenderingBufferProviderGetSize (GetCheckedHandle ()); + } + + [DllImport (Constants.CoreGraphicsLibrary)] + static extern IntPtr CGRenderingBufferLockBytePtr (IntPtr /* CGRenderingBufferProviderRef */ provider); + + /// Lock the pointer, and return it. + public IntPtr LockBytePointer () + { + return CGRenderingBufferLockBytePtr (GetCheckedHandle ()); + } + + [DllImport (Constants.CoreGraphicsLibrary)] + static extern void CGRenderingBufferUnlockBytePtr (IntPtr /* CGRenderingBufferProviderRef */ provider); + + /// Unlock the pointer. + public void UnlockBytePointer () + { + CGRenderingBufferUnlockBytePtr (GetCheckedHandle ()); + } + + [DllImport (Constants.CoreGraphicsLibrary)] + static extern nuint CGRenderingBufferProviderGetTypeID (); + + /// Get this type's CFTypeID. + [DllImport (Constants.CoreGraphicsLibrary, EntryPoint = "CGRenderingBufferProviderGetTypeID")] + public extern static /* CFTypeID */ nint GetTypeId (); +#endif // !COREBUILD + } +} diff --git a/src/CoreGraphics/CGShading.cs b/src/CoreGraphics/CGShading.cs index a64b0352d118..5d855e59190e 100644 --- a/src/CoreGraphics/CGShading.cs +++ b/src/CoreGraphics/CGShading.cs @@ -66,26 +66,22 @@ protected internal override void Release () extern static /* CGShadingRef */ IntPtr CGShadingCreateAxial (/* CGColorSpaceRef */ IntPtr space, CGPoint start, CGPoint end, /* CGFunctionRef */ IntPtr functionHandle, byte extendStart, byte extendEnd); - /// To be added. - /// To be added. - /// To be added. - /// To be added. - /// To be added. - /// To be added. - /// To be added. - /// To be added. - /// To be added. - public static CGShading CreateAxial (CGColorSpace colorspace, CGPoint start, CGPoint end, CGFunction function, bool extendStart, bool extendEnd) + /// Create a new axial shading. + /// The colorspace to use for the new . + /// The starting point for the axis. + /// The ending point for the axis + /// The shading function to use. + /// Whether the shading will extend beyond the starting point of the axis or not. + /// Whether the shading will extend beyond the ending point of the axis or not. + /// A new if successful, otherwise. + public static CGShading? CreateAxial (CGColorSpace? colorspace, CGPoint start, CGPoint end, CGFunction? function, bool extendStart, bool extendEnd) { - if (colorspace is null) - ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (colorspace)); - if (function is null) - ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (function)); - - CGShading result = new CGShading (CGShadingCreateAxial (colorspace.GetCheckedHandle (), start, end, function.GetCheckedHandle (), extendStart.AsByte (), extendEnd.AsByte ()), true); + var handle = CGShadingCreateAxial (colorspace.GetHandle (), start, end, function.GetHandle (), extendStart.AsByte (), extendEnd.AsByte ()); GC.KeepAlive (colorspace); GC.KeepAlive (function); - return result; + if (handle == IntPtr.Zero) + return null; + return new CGShading (handle, true); } [DllImport (Constants.CoreGraphicsLibrary)] @@ -93,19 +89,26 @@ public static CGShading CreateAxial (CGColorSpace colorspace, CGPoint start, CGP CGPoint start, /* CGFloat */ nfloat startRadius, CGPoint end, /* CGFloat */ nfloat endRadius, /* CGFunctionRef */ IntPtr function, byte extendStart, byte extendEnd); - public static CGShading CreateRadial (CGColorSpace colorspace, CGPoint start, nfloat startRadius, CGPoint end, nfloat endRadius, - CGFunction function, bool extendStart, bool extendEnd) + /// Create a new radial shading. + /// The colorspace to use for the new . + /// The center point for the starting circle. + /// The radius of the starting circle. + /// The center point for the ending circle + /// The radius of the ending circle. + /// The shading function to use. + /// Whether the shading will extend beyond the starting circle or not. + /// Whether the shading will extend beyond the ending circle or not. + /// A new if successful, otherwise. + public static CGShading? CreateRadial (CGColorSpace? colorspace, CGPoint start, nfloat startRadius, CGPoint end, nfloat endRadius, + CGFunction? function, bool extendStart, bool extendEnd) { - if (colorspace is null) - ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (colorspace)); - if (function is null) - ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (function)); - - CGShading result = new CGShading (CGShadingCreateRadial (colorspace.GetCheckedHandle (), start, startRadius, end, endRadius, - function.GetCheckedHandle (), extendStart.AsByte (), extendEnd.AsByte ()), true); + var handle =CGShadingCreateRadial (colorspace.GetHandle (), start, startRadius, end, endRadius, + function.GetHandle (), extendStart.AsByte (), extendEnd.AsByte ()); GC.KeepAlive (colorspace); GC.KeepAlive (function); - return result; + if (handle == IntPtr.Zero) + return null; + return new CGShading (handle, true); } [DllImport (Constants.CoreGraphicsLibrary)] @@ -113,6 +116,100 @@ public static CGShading CreateRadial (CGColorSpace colorspace, CGPoint start, nf [DllImport (Constants.CoreGraphicsLibrary)] extern static /* CGShadingRef */ IntPtr CGShadingRetain (/* CGShadingRef */ IntPtr shading); + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern IntPtr /* CGShadingRef __nullable */ CGShadingCreateAxialWithContentHeadroom ( + float headroom, + IntPtr /* CGColorSpaceRef cg_nullable */ space, + CGPoint start, + CGPoint end, + IntPtr /* CGFunctionRef cg_nullable */ function, + byte /* bool */ extendStart, + byte /* bool */ extendEnd); + + /// Create an axial shading with the specified content headroom. + /// The content headroom for the new . + /// The colorspace to use for the new . This colorspace must support HDR. + /// The starting point for the axis. + /// The ending point for the axis + /// The shading function to use. + /// Whether the shading will extend beyond the starting point of the axis or not. + /// Whether the shading will extend beyond the ending point of the axis or not. + /// A new if successful, otherwise. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public static CGShading? CreateAxial (float headroom, CGColorSpace? colorSpace, CGPoint start, CGPoint end, CGFunction? function, bool extendStart, bool extendEnd) + { + var handle = CGShadingCreateAxialWithContentHeadroom (headroom, colorSpace.GetHandle (), start, end, function.GetHandle (), extendStart.AsByte (), extendEnd.AsByte ()); + GC.KeepAlive (colorSpace); + GC.KeepAlive (function); + if (handle == IntPtr.Zero) + return null; + return new CGShading (handle, true); + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + extern static /* CGShadingRef */ IntPtr CGShadingCreateRadialWithContentHeadroom ( + float headroom, + /* CGColorSpaceRef cg_nullable */ IntPtr space, + CGPoint start, + /* CGFloat */ nfloat startRadius, + CGPoint end, + /* CGFloat */ nfloat endRadius, + /* CGFunctionRef cg_nullable */ IntPtr function, + byte extendStart, + byte extendEnd); + + /// Create a new radial shading with the specified content headroom. + /// The content headroom for the new . + /// The colorspace to use for the new . This colorspace must support HDR. + /// The center point for the starting circle. + /// The radius of the starting circle. + /// The center point for the ending circle + /// The radius of the ending circle. + /// The shading function to use. + /// Whether the shading will extend beyond the starting circle or not. + /// Whether the shading will extend beyond the ending circle or not. + /// A new if successful, otherwise. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public static CGShading? CreateRadial (float headroom, CGColorSpace? colorspace, CGPoint start, nfloat startRadius, CGPoint end, nfloat endRadius, CGFunction? function, bool extendStart, bool extendEnd) + { + var handle = CGShadingCreateRadialWithContentHeadroom (headroom, colorspace.GetHandle (), start, startRadius, end, endRadius, function.GetHandle (), extendStart.AsByte (), extendEnd.AsByte ()); + GC.KeepAlive (colorspace); + GC.KeepAlive (function); + if (handle == IntPtr.Zero) + return null; + return new CGShading (handle, true); + } + + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern float CGShadingGetContentHeadroom (IntPtr /* CGShadingRef gc_nullable */ shading); + + /// Get the content headroom for this shading. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public float ContentHeadroom { + get => CGShadingGetContentHeadroom (GetCheckedHandle ()); + } #endif // !COREBUILD } } diff --git a/src/CoreGraphics/CGToneMappingOptions.cs b/src/CoreGraphics/CGToneMappingOptions.cs new file mode 100644 index 000000000000..8af57bed240b --- /dev/null +++ b/src/CoreGraphics/CGToneMappingOptions.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Foundation; +using ObjCRuntime; + +namespace CoreGraphics { + /// A dictionary of tone mapping options. + partial class CGToneMappingOptions { + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + [DllImport (Constants.CoreGraphicsLibrary)] + static extern IntPtr /* CFDictionaryRef */ CGEXRToneMappingGammaGetDefaultOptions (); + + /// Get the default options for tone mapping using the EXR Gamma method. + [SupportedOSPlatform ("ios26.0")] + [SupportedOSPlatform ("tvos26.0")] + [SupportedOSPlatform ("maccatalyst26.0")] + [SupportedOSPlatform ("macos26.0")] + public static CGToneMappingOptions? GetDefaultExrToneMappingGammaOptions () + { + var handle = CGEXRToneMappingGammaGetDefaultOptions (); + var dict = Runtime.GetNSObject (handle); + if (dict is null) + return null; + return new CGToneMappingOptions (dict); + } + } +} diff --git a/src/DotNetGlobals.cs b/src/DotNetGlobals.cs index f35ba00b1d41..6d4f5bfc8cbc 100644 --- a/src/DotNetGlobals.cs +++ b/src/DotNetGlobals.cs @@ -1,4 +1,8 @@ global using System; global using System.Runtime.Versioning; // We need the SupportedOSPlatform/UnsupportedOSPlatform attributes pretty much everywhere +global using System.Runtime.InteropServices; + +global using Foundation; +global using ObjCRuntime; global using OSStatus = System.Int32; diff --git a/src/ObjCRuntime/Runtime.cs b/src/ObjCRuntime/Runtime.cs index b570a9b6d639..1c0a02730fdb 100644 --- a/src/ObjCRuntime/Runtime.cs +++ b/src/ObjCRuntime/Runtime.cs @@ -2331,6 +2331,34 @@ public static NativeHandle RetainAndAutoreleaseNativeObject (INativeObject? obj) return obj.GetHandle (); } + /// Retain and autorelease the given object, then return the object's handle. + /// The object to retain and autorelease. + /// The object's handle (retained and autorelease). + /// The behavior is undefined if the handle's type doesn't support the 'retain' and 'autorelease' selectors. + [EditorBrowsable (EditorBrowsableState.Never)] + internal static NativeHandle RetainAndAutoreleaseHandle (INativeObject? obj) + { + if (obj is null) + return NativeHandle.Zero; +#pragma warning disable RBI0014 + return RetainAndAutoreleaseHandle (obj.GetHandle ()); +#pragma warning restore RBI0014 + } + + /// Retain and autorelease the given handle, then return the handle. + /// The handle to retain and autorelease. + /// The handle (retained and autorelease). + /// The behavior is undefined if the handle's type doesn't support the 'retain' and 'autorelease' selectors. + [EditorBrowsable (EditorBrowsableState.Never)] + internal static NativeHandle RetainAndAutoreleaseHandle (NativeHandle handle) + { + if (handle == NativeHandle.Zero) + return NativeHandle.Zero; + NSObject.DangerousRetain (handle); + NSObject.DangerousAutorelease (handle); + return handle; + } + static IntPtr CopyAndAutorelease (IntPtr ptr) { ptr = Messaging.IntPtr_objc_msgSend (ptr, Selector.GetHandle ("copy")); diff --git a/src/corefoundation.cs b/src/corefoundation.cs index 87afbd9bcb11..1954ff632050 100644 --- a/src/corefoundation.cs +++ b/src/corefoundation.cs @@ -168,4 +168,11 @@ public enum OSLogLevel : byte { Error = 0x10, Fault = 0x11, } + + [Native] + public enum CFByteOrder : long { + Unknown, + LittleEndian, + BigEndian + } } diff --git a/src/coregraphics.cs b/src/coregraphics.cs index 50cede44cd00..0f317531dcf8 100644 --- a/src/coregraphics.cs +++ b/src/coregraphics.cs @@ -629,6 +629,21 @@ partial interface CGToneMappingOptionKeys { [Internal] [Field ("kCGEXRToneMappingGammaKneeHigh")] NSString ExrToneMappingGammaKneeHighKey { get; } + + [Internal] + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + [Field ("kCGPreferredDynamicRange")] + NSString PreferredDynamicRangeKey { get; } + + [Internal] + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + [Field ("kCGContentAverageLightLevel")] + NSString ContentAverageLightLevelKey { get; } + + [Internal] + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + [Field ("kCGContentAverageLightLevelNits")] + NSString ContentAverageLightLevelNitsKey { get; } } [TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)] @@ -641,6 +656,17 @@ interface CGToneMappingOptions { float ExrToneMappingGammaExposure { get; set; } float ExrToneMappingGammaKneeLow { get; set; } float ExrToneMappingGammaKneeHigh { get; set; } + + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + CGDynamicRange PreferredDynamicRange { get; set; } + + // property type deduced from similarly named properties on other classes + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + float ContentAverageLightLevel { get; set; } + + // property type: I've never seen floating-point nits, so use an integer type + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + nint ContentAverageLightLevelNits { get; } } [TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)] @@ -650,4 +676,83 @@ interface CoreGraphicsFields { [Field ("kCGDefaultHDRImageContentHeadroom")] float DefaultHdrImageContentHeadroom { get; } } + + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + [Flags] + public enum CGColorModel : uint + { + NoColorant = 0u << 0, + Gray = 1u << 0, + Rgb = 1u << 1, + Cmyk = 1u << 2, + Lab = 1u << 3, + DeviceN = 1u << 4, + } + + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + public enum CGComponent : uint + { + Unknown = 0, + Integer8Bit = 1, + Integer10Bit = 6, + Integer16Bit = 2, + Integer32Bit = 3, + Float16Bit = 5, + Float32Bit = 4, + } + + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + public enum CGBitmapLayout : uint + { + AlphaOnly, + Gray, + GrayAlpha, + Rgba, + Argb, + Rgbx, + Xrgb, + Bgra, + Bgrx, + Abgr, + Xbgr, + Cmyk, + } + + [Partial] + interface CGAdaptiveKeys + { + [Field ("kCGAdaptiveMaximumBitDepth")] + NSString MaximumBitDepthKey { get; } + } + + [StrongDictionary ("CGAdaptiveKeys")] + interface CGAdaptiveOptions { + CGComponent MaximumBitDepth { get; set; } + } + + public enum CGImageComponentInfo : uint + { + Integer = (0u << 8), + Float = (1u << 8), + } + + [Flags] + public enum CGBitmapInfo : uint { + AlphaInfoMask = 0x1F, + ComponentInfoMask = 0xF00, + ByteOrderInfoMask = 0x7000, + PixelFormatInfoMask = 0xF0000, + } + + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] + enum CGDynamicRange { + [Field ("kCGDynamicRangeHigh")] + High, + + [Field ("kCGDynamicRangeConstrained")] + Constrained, + + [Field ("kCGDynamicRangeStandard")] + Standard, + } } diff --git a/src/frameworks.sources b/src/frameworks.sources index f9a813b47a22..0d5f4d89e45f 100644 --- a/src/frameworks.sources +++ b/src/frameworks.sources @@ -504,8 +504,12 @@ COREGRAPHICS_CORE_SOURCES = \ COREGRAPHICS_SOURCES = \ CoreGraphics/CGBitmapContext.cs \ + CoreGraphics/CGBitmapInfo.cs \ + CoreGraphics/CGBitmapParameters.cs \ CoreGraphics/CGContextPDF.cs \ CoreGraphics/CGColorConversionInfo.cs \ + CoreGraphics/CGContentInfo.cs \ + CoreGraphics/CGContentToneMappingInfo.cs \ CoreGraphics/CGDataConsumer.cs \ CoreGraphics/CGDataProvider.cs \ CoreGraphics/CGEventSource.cs \ @@ -523,8 +527,10 @@ COREGRAPHICS_SOURCES = \ CoreGraphics/CGPDFStream.cs \ CoreGraphics/CGPDFString.cs \ CoreGraphics/CGPdfTagType.cs \ + CoreGraphics/CGRenderingBufferProvider.cs \ CoreGraphics/CGSession.cs \ CoreGraphics/CGShading.cs \ + CoreGraphics/CGToneMappingOptions.cs \ CoreGraphics/NativeDrawingMethods.cs \ CoreGraphics/NSValue.cs \ diff --git a/tests/cecil-tests/Documentation.KnownFailures.txt b/tests/cecil-tests/Documentation.KnownFailures.txt index eaec6c7121b3..ce942db8c90e 100644 --- a/tests/cecil-tests/Documentation.KnownFailures.txt +++ b/tests/cecil-tests/Documentation.KnownFailures.txt @@ -1935,6 +1935,9 @@ F:CoreData.NSPersistentCloudKitContainerSchemaInitializationOptions.DryRun F:CoreData.NSPersistentCloudKitContainerSchemaInitializationOptions.None F:CoreData.NSPersistentCloudKitContainerSchemaInitializationOptions.PrintSchema F:CoreData.NSPersistentStoreRequestType.BatchInsert +F:CoreFoundation.CFByteOrder.BigEndian +F:CoreFoundation.CFByteOrder.LittleEndian +F:CoreFoundation.CFByteOrder.Unknown F:CoreFoundation.CFComparisonResult.EqualTo F:CoreFoundation.CFComparisonResult.GreaterThan F:CoreFoundation.CFComparisonResult.LessThan @@ -1954,15 +1957,49 @@ F:CoreGraphics.CGAffineTransform.C F:CoreGraphics.CGAffineTransform.D F:CoreGraphics.CGAffineTransform.Tx F:CoreGraphics.CGAffineTransform.Ty +F:CoreGraphics.CGBitmapInfo.AlphaInfoMask +F:CoreGraphics.CGBitmapInfo.ByteOrderInfoMask +F:CoreGraphics.CGBitmapInfo.ComponentInfoMask +F:CoreGraphics.CGBitmapInfo.PixelFormatInfoMask +F:CoreGraphics.CGBitmapLayout.Abgr +F:CoreGraphics.CGBitmapLayout.AlphaOnly +F:CoreGraphics.CGBitmapLayout.Argb +F:CoreGraphics.CGBitmapLayout.Bgra +F:CoreGraphics.CGBitmapLayout.Bgrx +F:CoreGraphics.CGBitmapLayout.Cmyk +F:CoreGraphics.CGBitmapLayout.Gray +F:CoreGraphics.CGBitmapLayout.GrayAlpha +F:CoreGraphics.CGBitmapLayout.Rgba +F:CoreGraphics.CGBitmapLayout.Rgbx +F:CoreGraphics.CGBitmapLayout.Xbgr +F:CoreGraphics.CGBitmapLayout.Xrgb F:CoreGraphics.CGColorConversionInfoTriple.Intent F:CoreGraphics.CGColorConversionInfoTriple.Space F:CoreGraphics.CGColorConversionInfoTriple.Transform +F:CoreGraphics.CGColorModel.Cmyk +F:CoreGraphics.CGColorModel.DeviceN +F:CoreGraphics.CGColorModel.Gray +F:CoreGraphics.CGColorModel.Lab +F:CoreGraphics.CGColorModel.NoColorant +F:CoreGraphics.CGColorModel.Rgb +F:CoreGraphics.CGComponent.Float16Bit +F:CoreGraphics.CGComponent.Float32Bit +F:CoreGraphics.CGComponent.Integer10Bit +F:CoreGraphics.CGComponent.Integer16Bit +F:CoreGraphics.CGComponent.Integer32Bit +F:CoreGraphics.CGComponent.Integer8Bit +F:CoreGraphics.CGComponent.Unknown F:CoreGraphics.CGConstantColor.Black F:CoreGraphics.CGConstantColor.Clear F:CoreGraphics.CGConstantColor.White +F:CoreGraphics.CGDynamicRange.Constrained +F:CoreGraphics.CGDynamicRange.High +F:CoreGraphics.CGDynamicRange.Standard F:CoreGraphics.CGEventSuppressionState.NumberOfEventSuppressionStates F:CoreGraphics.CGEventType.TapDisabledByTimeout F:CoreGraphics.CGEventType.TapDisabledByUserInput +F:CoreGraphics.CGImageComponentInfo.Float +F:CoreGraphics.CGImageComponentInfo.Integer F:CoreGraphics.CGPdfTagType.Annotation F:CoreGraphics.CGPdfTagType.Art F:CoreGraphics.CGPdfTagType.Bibliography @@ -10000,6 +10037,7 @@ M:CoreFoundation.OSLog.Log(CoreFoundation.OSLogLevel,System.String) M:CoreFoundation.OSLog.Log(System.String) M:CoreFoundation.OSLog.Release M:CoreFoundation.OSLog.Retain +M:CoreGraphics.CGAdaptiveKeys.#ctor M:CoreGraphics.CGAffineTransform.#ctor(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat) M:CoreGraphics.CGAffineTransform.Decompose M:CoreGraphics.CGAffineTransform.MakeRotation(System.Runtime.InteropServices.NFloat) @@ -10238,7 +10276,6 @@ M:CoreGraphics.CGRectExtensions.IsInfinite(CoreGraphics.CGRect) M:CoreGraphics.CGRectExtensions.IsNull(CoreGraphics.CGRect) M:CoreGraphics.CGRectExtensions.Standardize(CoreGraphics.CGRect) M:CoreGraphics.CGRectExtensions.UnionWith(CoreGraphics.CGRect,CoreGraphics.CGRect) -M:CoreGraphics.CGShading.CreateRadial(CoreGraphics.CGColorSpace,CoreGraphics.CGPoint,System.Runtime.InteropServices.NFloat,CoreGraphics.CGPoint,System.Runtime.InteropServices.NFloat,CoreGraphics.CGFunction,System.Boolean,System.Boolean) M:CoreGraphics.CGShading.Release M:CoreGraphics.CGShading.Retain M:CoreGraphics.CGSize.#ctor(System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat) @@ -19448,6 +19485,7 @@ P:CoreFoundation.CFSocket.Address P:CoreFoundation.CFSocket.RemoteAddress P:CoreFoundation.CFString.Item(System.IntPtr) P:CoreFoundation.OSLog.Default +P:CoreGraphics.CGAdaptiveOptions.MaximumBitDepth P:CoreGraphics.CGColor.AXName P:CoreGraphics.CGColorSpace.IsHdr P:CoreGraphics.CGColorSpace.IsHlgBased @@ -19467,10 +19505,13 @@ P:CoreGraphics.CGSessionProperties.LoginDone P:CoreGraphics.CGSessionProperties.OnConsole P:CoreGraphics.CGSessionProperties.UserId P:CoreGraphics.CGSessionProperties.UserName +P:CoreGraphics.CGToneMappingOptions.ContentAverageLightLevel +P:CoreGraphics.CGToneMappingOptions.ContentAverageLightLevelNits P:CoreGraphics.CGToneMappingOptions.ExrToneMappingGammaDefog P:CoreGraphics.CGToneMappingOptions.ExrToneMappingGammaExposure P:CoreGraphics.CGToneMappingOptions.ExrToneMappingGammaKneeHigh P:CoreGraphics.CGToneMappingOptions.ExrToneMappingGammaKneeLow +P:CoreGraphics.CGToneMappingOptions.PreferredDynamicRange P:CoreGraphics.CGToneMappingOptions.SkipBoostToHdr P:CoreGraphics.CGToneMappingOptions.Use100nitsHlgOotf P:CoreGraphics.CGToneMappingOptions.UseBT1886ForCoreVideoGamma @@ -26567,27 +26608,43 @@ T:CoreData.NSPersistentHistoryToken T:CoreData.NSPersistentHistoryTransaction T:CoreData.NSStagedMigrationManager T:CoreFoundation.CFArray +T:CoreFoundation.CFByteOrder T:CoreFoundation.CFComparisonResult T:CoreFoundation.CFStringTransform T:CoreFoundation.CGAffineTransformComponents T:CoreFoundation.OSLog T:CoreFoundation.OSLogLevel +T:CoreGraphics.CGAdaptiveKeys +T:CoreGraphics.CGAdaptiveOptions +T:CoreGraphics.CGBitmapContext.OnAllocateCallback +T:CoreGraphics.CGBitmapContext.OnErrorCallback +T:CoreGraphics.CGBitmapContext.OnFreeCallback +T:CoreGraphics.CGBitmapContext.OnResolveCallback +T:CoreGraphics.CGBitmapInfo +T:CoreGraphics.CGBitmapInfoExtensions +T:CoreGraphics.CGBitmapLayout T:CoreGraphics.CGColorConversionInfoTransformType T:CoreGraphics.CGColorConversionOptions +T:CoreGraphics.CGColorModel +T:CoreGraphics.CGComponent T:CoreGraphics.CGConstantColor T:CoreGraphics.CGDisplayStreamKeys T:CoreGraphics.CGDisplayStreamYCbCrMatrixOptionKeys +T:CoreGraphics.CGDynamicRange +T:CoreGraphics.CGImageComponentInfo T:CoreGraphics.CGPDFAccessPermissions T:CoreGraphics.CGPDFOutlineOptions T:CoreGraphics.CGPdfTagProperties T:CoreGraphics.CGPdfTagType T:CoreGraphics.CGPdfTagType_Extensions +T:CoreGraphics.CGRenderingBufferProvider.LockPointerCallback +T:CoreGraphics.CGRenderingBufferProvider.ReleaseInfoCallback +T:CoreGraphics.CGRenderingBufferProvider.UnlockPointerCallback T:CoreGraphics.CGSession T:CoreGraphics.CGSessionKeys T:CoreGraphics.CGSessionProperties T:CoreGraphics.CGToneMapping T:CoreGraphics.CGToneMappingOptionKeys -T:CoreGraphics.CGToneMappingOptions T:CoreGraphics.MatrixOrder T:CoreGraphics.NMatrix2 T:CoreGraphics.NMatrix3 diff --git a/tests/introspection/ApiCMAttachmentTest.cs b/tests/introspection/ApiCMAttachmentTest.cs index 0126d428cc0e..0b685316812f 100644 --- a/tests/introspection/ApiCMAttachmentTest.cs +++ b/tests/introspection/ApiCMAttachmentTest.cs @@ -248,6 +248,7 @@ protected virtual bool Skip (string nativeName) #endif return false; case "MTLIOCompressionContext": + case "CGRenderingBufferProvider": return true; default: return false; diff --git a/tests/monotouch-test/CoreGraphics/BitmapContextTest.cs b/tests/monotouch-test/CoreGraphics/BitmapContextTest.cs index f08bb0e1e197..59cae7b36e81 100644 --- a/tests/monotouch-test/CoreGraphics/BitmapContextTest.cs +++ b/tests/monotouch-test/CoreGraphics/BitmapContextTest.cs @@ -8,6 +8,8 @@ // using System; +using System.Runtime.InteropServices; + using Foundation; using CoreGraphics; using NUnit.Framework; @@ -110,5 +112,169 @@ public void ToImage () Assert.Null (c.ToImage (), "ToImage/Disposed"); } } + + [Test] + public void CreateAdaptive () + { + TestRuntime.AssertXcodeVersion (26, 0); + + nuint width = 256; + nuint height = 256; + + { + using var context = CGBitmapContext.Create (width, height, (NSDictionary?) null, null, null, null, null); + Assert.NotNull (context, "Context#1"); + } + + { + var calledOnResolve = false; + var calledOnAllocate = false; + var calledOnFree = false; + var calledOnError = false; + using var context = CGBitmapContext.Create (width, height, (CGAdaptiveOptions?) null, + (ref CGContentInfo info, ref CGBitmapParameters parameters) => + { + Console.WriteLine ($"CreateAdaptive () OnResolve#2 info={info} parameters={parameters}"); + calledOnResolve = true; + return true; + }, + (ref CGContentInfo info, ref CGBitmapParameters parameters) => { + Console.WriteLine ($"CreateAdaptive () OnAllocate#2 info={info} parameters={parameters}"); + calledOnAllocate = true; + return null; + }, + (CGRenderingBufferProvider renderingBufferProvider, ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters) => { + Console.WriteLine ($"CreateAdaptive () OnFree#2 renderingBufferProvider={renderingBufferProvider} contentInfo={contentInfo} bitmapParameters={bitmapParameters}"); + calledOnFree = true; + }, + (NSError error, ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters) => { + Console.WriteLine ($"CreateAdaptive () OnError#2 error={error} contentInfo={contentInfo} bitmapParameters={bitmapParameters}"); + calledOnError = true; + }); + + Assert.NotNull (context, "Context#2"); + + // This fails because onAllocate returns null + using var img = context.ToImage (); + Assert.Null (img, "ToImage"); + + Assert.That (calledOnResolve, Is.True, "calledOnResolve#2"); + Assert.That (calledOnAllocate, Is.True, "calledOnAllocate#2"); + Assert.That (calledOnFree, Is.False, "calledOnFree#2"); + Assert.That (calledOnError, Is.True, "calledOnError#2"); + } + + { + var calledOnResolve = false; + var calledOnAllocate = false; + var calledOnFree = false; + var calledOnError = false; + var options = new CGAdaptiveOptions () { + MaximumBitDepth = CGComponent.Float16Bit, + }; + using var context = CGBitmapContext.Create (width, height, options, + (ref CGContentInfo info, ref CGBitmapParameters parameters) => + { + Console.WriteLine ($"CreateAdaptive () OnResolve#3 info={info} parameters={parameters}"); + calledOnResolve = true; + return true; + }, + (ref CGContentInfo info, ref CGBitmapParameters parameters) => { + Console.WriteLine ($"CreateAdaptive () OnAllocate#3 info={info} parameters={parameters}"); + calledOnAllocate = true; + return null; + }, + (CGRenderingBufferProvider renderingBufferProvider, ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters) => { + Console.WriteLine ($"CreateAdaptive () OnFree#3 renderingBufferProvider={renderingBufferProvider} contentInfo={contentInfo} bitmapParameters={bitmapParameters}"); + calledOnFree = true; + }, + (NSError error, ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters) => { + Console.WriteLine ($"CreateAdaptive () OnError#3 error={error} contentInfo={contentInfo} bitmapParameters={bitmapParameters}"); + calledOnError = true; + }); + + Assert.NotNull (context, "Context#3"); + + // This fails because onAllocate returns null + using var img = context.ToImage (); + Assert.Null (img, "ToImage"); + + Assert.That (calledOnResolve, Is.True, "calledOnResolve#3"); + Assert.That (calledOnAllocate, Is.True, "calledOnAllocate#3"); + Assert.That (calledOnFree, Is.False, "calledOnFree#3"); + Assert.That (calledOnError, Is.True, "calledOnError#3"); + } + + + { + var calledOnLockPointer = false; + var calledOnUnlockPointer = false; + var calledOnReleaseInfo = false; + const int renderingBufferProviderSize = 512; + using (var renderingBufferProvider = CGRenderingBufferProvider.Create (IntPtr.Zero, renderingBufferProviderSize, + lockPointer: (info) => { + calledOnLockPointer = true; + var rv = Marshal.AllocHGlobal (renderingBufferProviderSize); + // Console.WriteLine ($"CreateAdaptive () OnLockPointer#4 ({info}) => {rv}"); + return rv; + }, + unlockPointer: (info, pointer) => { + // Console.WriteLine ($"CreateAdaptive () OnUnlockPointer#4 ({info}, {pointer})"); + calledOnUnlockPointer = true; + Marshal.FreeHGlobal (pointer); + }, + releaseInfo: (info) => { + // Console.WriteLine ($"CreateAdaptive () OnReleaseInfo#4 ({info})"); + calledOnReleaseInfo = true; + } + )) { + Assert.That (renderingBufferProvider, Is.Not.Null, "RenderingBufferProvider"); + + var calledOnResolve = false; + var calledOnAllocate = false; + var calledOnFree = false; + var calledOnError = false; + var options = new CGAdaptiveOptions () { + MaximumBitDepth = CGComponent.Float16Bit, + }; + + using (var context = CGBitmapContext.Create (width, height, options, + (ref CGContentInfo info, ref CGBitmapParameters parameters) => + { + // Console.WriteLine ($"CreateAdaptive () OnResolve#4 info={info} parameters={parameters}"); + calledOnResolve = true; + return true; + }, + (ref CGContentInfo info, ref CGBitmapParameters parameters) => { + // Console.WriteLine ($"CreateAdaptive () OnAllocate#4 info={info} parameters={parameters}"); + calledOnAllocate = true; + return renderingBufferProvider; + }, + (CGRenderingBufferProvider renderingBufferProvider, ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters) => { + // Console.WriteLine ($"CreateAdaptive () OnFree#4 renderingBufferProvider={renderingBufferProvider} contentInfo={contentInfo} bitmapParameters={bitmapParameters}"); + calledOnFree = true; + }, + (NSError error, ref CGContentInfo contentInfo, ref CGBitmapParameters bitmapParameters) => { + // Console.WriteLine ($"CreateAdaptive () OnError#4 error={error} contentInfo={contentInfo} bitmapParameters={bitmapParameters}"); + calledOnError = true; + })) { + + Assert.NotNull (context, "Context#4"); + + using var img = context.ToImage (); + Assert.NotNull (img, "ToImage"); + } + + Assert.That (calledOnResolve, Is.True, "calledOnResolve#4"); + Assert.That (calledOnAllocate, Is.True, "calledOnAllocate#4"); + Assert.That (calledOnFree, Is.True, "calledOnFree#4"); + Assert.That (calledOnError, Is.False, "calledOnError#4"); + } + + Assert.That (calledOnLockPointer, Is.True, "calledOnLockPointer#4"); + Assert.That (calledOnUnlockPointer, Is.True, "calledOnUnlockPointer#4"); + Assert.That (calledOnReleaseInfo, Is.False, "calledOnReleaseInfo#4"); + } + } } } diff --git a/tests/monotouch-test/CoreGraphics/CGBitmapInfoTest.cs b/tests/monotouch-test/CoreGraphics/CGBitmapInfoTest.cs new file mode 100644 index 000000000000..beb200179142 --- /dev/null +++ b/tests/monotouch-test/CoreGraphics/CGBitmapInfoTest.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using CoreGraphics; + +namespace MonoTouchFixtures.CoreGraphics { + + [TestFixture] + [Preserve (AllMembers = true)] + public class CGBitmapInfoTest { + [Test] + public void Extensions () + { + Assert.AreEqual (CGImageAlphaInfo.PremultipliedLast, ((CGBitmapInfo) CGImageAlphaInfo.PremultipliedLast).GetAlphaInfo (), "GetAlphaInfo"); + Assert.AreEqual (CGImageComponentInfo.Float, ((CGBitmapInfo) CGImageComponentInfo.Float).GetComponentInfo (), "CGImageComponentInfo"); + Assert.AreEqual (CGImageByteOrderInfo.ByteOrder32Little, ((CGBitmapInfo) CGImageByteOrderInfo.ByteOrder32Little).GetByteOrderInfo (), "CGImageByteOrderInfo"); + Assert.AreEqual (CGImagePixelFormatInfo.Rgb101010, ((CGBitmapInfo) CGImagePixelFormatInfo.Rgb101010).GetPixelFormatInfo (), "CGImagePixelFormatInfo"); + } + } +} diff --git a/tests/monotouch-test/CoreGraphics/CGBitmapParametersTest.cs b/tests/monotouch-test/CoreGraphics/CGBitmapParametersTest.cs new file mode 100644 index 000000000000..94b95e0db713 --- /dev/null +++ b/tests/monotouch-test/CoreGraphics/CGBitmapParametersTest.cs @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using CoreFoundation; + +using CoreGraphics; + +namespace MonoTouchFixtures.CoreGraphics { + + [TestFixture] + [Preserve (AllMembers = true)] + public class CGBitmapParametersTest { + [Test] + public void DefaultValuesTest () + { + Assert.Multiple (() => { + var p = new CGBitmapParameters (); + Assert.AreEqual ((nuint) 0u, p.Width, "Width"); + Assert.AreEqual ((nuint) 0u, p.Height, "Height"); + Assert.AreEqual ((nuint) 0u, p.BytesPerPixel, "BytesPerPixel"); + Assert.AreEqual ((nuint) 0u, p.AlignedBytesPerRow, "AlignedBytesPerRow"); + Assert.AreEqual (default(CGComponent), p.Component, "Component"); + Assert.AreEqual (default(CGBitmapLayout), p.Layout, "Layout"); + Assert.AreEqual (default(CGImagePixelFormatInfo), p.Format, "Format"); + Assert.AreEqual (IntPtr.Zero, p.ColorSpaceHandle, "ColorSpaceHandle"); + Assert.AreEqual (false, p.HasPremultipliedAlpha, "HasPremultipliedAlpha"); + Assert.AreEqual ((CFByteOrder)0, p.ByteOrder, "ByteOrder"); + Assert.AreEqual (0f, p.EdrTargetHeadroom, "EdrTargetHeadroom"); + }); + } + + [Test] + public void PropertySetGetTest () + { + Assert.Multiple (() => { + var p = new CGBitmapParameters (); + p.Width = 123u; + p.Height = 456u; + p.BytesPerPixel = 4u; + p.AlignedBytesPerRow = 512u; + p.Component = (CGComponent)1; + p.Layout = (CGBitmapLayout)2; + p.Format = (CGImagePixelFormatInfo)3; + p.ColorSpaceHandle = new IntPtr (0xDEADBEEF); + p.HasPremultipliedAlpha = true; + p.ByteOrder = CFByteOrder.LittleEndian; + p.EdrTargetHeadroom = 1.5f; + + Assert.AreEqual ((nuint) 123u, p.Width, "Width"); + Assert.AreEqual ((nuint) 456u, p.Height, "Height"); + Assert.AreEqual ((nuint) 4u, p.BytesPerPixel, "BytesPerPixel"); + Assert.AreEqual ((nuint) 512u, p.AlignedBytesPerRow, "AlignedBytesPerRow"); + Assert.AreEqual ((CGComponent)1, p.Component, "Component"); + Assert.AreEqual ((CGBitmapLayout)2, p.Layout, "Layout"); + Assert.AreEqual ((CGImagePixelFormatInfo)3, p.Format, "Format"); + Assert.AreEqual (new IntPtr (0xDEADBEEF), p.ColorSpaceHandle, "ColorSpaceHandle"); + Assert.IsTrue (p.HasPremultipliedAlpha, "HasPremultipliedAlpha"); + Assert.AreEqual (CFByteOrder.LittleEndian, p.ByteOrder, "ByteOrder"); + Assert.AreEqual (1.5f, p.EdrTargetHeadroom, "EdrTargetHeadroom"); + }); + } + + [Test] + public void HasPremultipliedAlphaFalseTest () + { + var p = new CGBitmapParameters (); + p.HasPremultipliedAlpha = false; + Assert.IsFalse (p.HasPremultipliedAlpha, "HasPremultipliedAlpha"); + } + + [Test] + public void ByteOrderTest () + { + var p = new CGBitmapParameters (); + p.ByteOrder = CFByteOrder.BigEndian; + Assert.AreEqual (CFByteOrder.BigEndian, p.ByteOrder, "ByteOrder"); + p.ByteOrder = CFByteOrder.LittleEndian; + Assert.AreEqual (CFByteOrder.LittleEndian, p.ByteOrder, "ByteOrder"); + } + } +} diff --git a/tests/monotouch-test/CoreGraphics/CGContentInfoTest.cs b/tests/monotouch-test/CoreGraphics/CGContentInfoTest.cs new file mode 100644 index 000000000000..c50df8af5275 --- /dev/null +++ b/tests/monotouch-test/CoreGraphics/CGContentInfoTest.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using Foundation; +using CoreGraphics; +using NUnit.Framework; +using ObjCRuntime; + +namespace MonoTouchFixtures.CoreGraphics { + [TestFixture] + [Preserve (AllMembers = true)] + public class CGContentInfoTest { + [Test] + public void DefaultValuesTest () + { + var c = new CGContentInfo (); + Assert.AreEqual (default(CGComponent), c.DeepestImageComponent, "DeepestImageComponent"); + Assert.AreEqual (default(CGColorModel), c.ContentColorModels, "ContentColorModels"); + Assert.IsFalse (c.HasWideGamut, "HasWideGamut"); + Assert.IsFalse (c.HasTransparency, "HasTransparency"); + Assert.AreEqual (0f, c.LargestContentHeadroom, "LargestContentHeadroom"); + } + + [Test] + public void PropertySetGetTest () + { + var c = new CGContentInfo (); + c.DeepestImageComponent = (CGComponent)2; + c.ContentColorModels = (CGColorModel)3; + c.HasWideGamut = true; + c.HasTransparency = true; + c.LargestContentHeadroom = 1.25f; + + Assert.AreEqual ((CGComponent)2, c.DeepestImageComponent, "DeepestImageComponent"); + Assert.AreEqual ((CGColorModel)3, c.ContentColorModels, "ContentColorModels"); + Assert.IsTrue (c.HasWideGamut, "HasWideGamut"); + Assert.IsTrue (c.HasTransparency, "HasTransparency"); + Assert.AreEqual (1.25f, c.LargestContentHeadroom, "LargestContentHeadroom"); + } + + [Test] + public void HasWideGamutFalseTest () + { + var c = new CGContentInfo (); + c.HasWideGamut = false; + Assert.IsFalse (c.HasWideGamut, "HasWideGamut"); + } + + [Test] + public void HasTransparencyFalseTest () + { + var c = new CGContentInfo (); + c.HasTransparency = false; + Assert.IsFalse (c.HasTransparency, "HasTransparency"); + } + } +} diff --git a/tests/monotouch-test/CoreGraphics/CGContentToneMappingInfoTest.cs b/tests/monotouch-test/CoreGraphics/CGContentToneMappingInfoTest.cs new file mode 100644 index 000000000000..9129674c8a11 --- /dev/null +++ b/tests/monotouch-test/CoreGraphics/CGContentToneMappingInfoTest.cs @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using Foundation; +using CoreGraphics; +using NUnit.Framework; +using ObjCRuntime; + +namespace MonoTouchFixtures.CoreGraphics { + [TestFixture] + [Preserve (AllMembers = true)] + public class CGContentToneMappingInfoTest { + [Test] + public void DefaultValuesTest () + { + var t = new CGContentToneMappingInfo (); + Assert.AreEqual (CGToneMapping.Default, t.Method, "Method"); + Assert.IsNull (t.Options, "Options"); + Assert.IsNull (t.ToneMappingOptions, "ToneMappingOptions"); + } + + [Test] + public void PropertySetGetTest () + { + var t = new CGContentToneMappingInfo (); + t.Method = CGToneMapping.ImageSpecificLumaScaling; + Assert.AreEqual (CGToneMapping.ImageSpecificLumaScaling, t.Method, "Method#1"); + t.Method = CGToneMapping.Default; + Assert.AreEqual (CGToneMapping.Default, t.Method, "Method#2"); + + using var dict = new NSDictionary (); + t.Options = dict; + Assert.AreSame (dict, t.Options, "Options#1"); + var toneMappingOptions = t.ToneMappingOptions!; + Assert.AreSame (dict, toneMappingOptions.Dictionary, "ToneMappingOptions#1"); + + Assert.IsFalse (toneMappingOptions.Use100nitsHlgOotf.HasValue, "ToneMappingOptions.Use100nitsHlgOotf #1"); + Assert.IsFalse (toneMappingOptions.UseBT1886ForCoreVideoGamma.HasValue, "ToneMappingOptions.UseBT1886ForCoreVideoGamma #1"); + Assert.IsFalse (toneMappingOptions.SkipBoostToHdr.HasValue, "ToneMappingOptions.SkipBoostToHdr #1"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaDefog.HasValue, "ToneMappingOptions.ExrToneMappingGammaDefog #1"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaExposure.HasValue, "ToneMappingOptions.ExrToneMappingGammaExposure #1"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaKneeLow.HasValue, "ToneMappingOptions.ExrToneMappingGammaKneeLow #1"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaKneeHigh.HasValue, "ToneMappingOptions.ExrToneMappingGammaKneeHigh #1"); + + using var mutableDict = new NSMutableDictionary (); + t.Options = mutableDict; + Assert.AreSame (mutableDict, t.Options, "Options#2"); + toneMappingOptions = t.ToneMappingOptions!; + Assert.AreSame (mutableDict, toneMappingOptions.Dictionary, "ToneMappingOptions#2"); + + Assert.IsFalse (toneMappingOptions.Use100nitsHlgOotf.HasValue, "ToneMappingOptions.Use100nitsHlgOotf #2"); + Assert.IsFalse (toneMappingOptions.UseBT1886ForCoreVideoGamma.HasValue, "ToneMappingOptions.UseBT1886ForCoreVideoGamma #2"); + Assert.IsFalse (toneMappingOptions.SkipBoostToHdr.HasValue, "ToneMappingOptions.SkipBoostToHdr #2"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaDefog.HasValue, "ToneMappingOptions.ExrToneMappingGammaDefog #2"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaExposure.HasValue, "ToneMappingOptions.ExrToneMappingGammaExposure #2"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaKneeLow.HasValue, "ToneMappingOptions.ExrToneMappingGammaKneeLow #2"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaKneeHigh.HasValue, "ToneMappingOptions.ExrToneMappingGammaKneeHigh #2"); + + toneMappingOptions.Use100nitsHlgOotf = false; + toneMappingOptions.UseBT1886ForCoreVideoGamma = true; + toneMappingOptions.SkipBoostToHdr = null; + toneMappingOptions.ExrToneMappingGammaDefog = 1.0f; + toneMappingOptions.ExrToneMappingGammaExposure = -1.0f; + toneMappingOptions.ExrToneMappingGammaKneeLow = 0.0f; + toneMappingOptions.ExrToneMappingGammaKneeHigh = null; + + Assert.IsFalse (toneMappingOptions.Use100nitsHlgOotf.Value, "ToneMappingOptions.Use100nitsHlgOotf #3"); + Assert.IsTrue (toneMappingOptions.UseBT1886ForCoreVideoGamma.Value, "ToneMappingOptions.UseBT1886ForCoreVideoGamma #3"); + Assert.IsFalse (toneMappingOptions.SkipBoostToHdr.HasValue, "ToneMappingOptions.SkipBoostToHdr #3"); + Assert.AreEqual (1.0f, toneMappingOptions.ExrToneMappingGammaDefog.Value, "ToneMappingOptions.ExrToneMappingGammaDefog #3"); + Assert.AreEqual (-1.0f, toneMappingOptions.ExrToneMappingGammaExposure.Value, "ToneMappingOptions.ExrToneMappingGammaExposure #3"); + Assert.AreEqual (0.0f, toneMappingOptions.ExrToneMappingGammaKneeLow.Value, "ToneMappingOptions.ExrToneMappingGammaKneeLow #3"); + Assert.IsFalse (toneMappingOptions.ExrToneMappingGammaKneeHigh.HasValue, "ToneMappingOptions.ExrToneMappingGammaKneeHigh #3"); + } + } +} diff --git a/tests/monotouch-test/CoreGraphics/CGImageTest.cs b/tests/monotouch-test/CoreGraphics/CGImageTest.cs index ba4b7d25dddb..9977228886f0 100644 --- a/tests/monotouch-test/CoreGraphics/CGImageTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGImageTest.cs @@ -64,6 +64,22 @@ public void ContentHeadroom () Assert.IsFalse (copy.ContainsImageSpecificToneMappingMetadata, "ContainsImageSpecificToneMappingMetadata B"); Assert.AreEqual (4.92610836f, CGImage.DefaultHdrImageContentHeadroom, "DefaultHdrImageContentHeadroom"); + + if (TestRuntime.CheckXcodeVersion (26, 0)) { + Assert.That (copy.CalculatedContentHeadroom, Is.EqualTo (0.0f), "CalculatedContentHeadroom B"); + Assert.That (copy.ContentAverageLightLevel, Is.EqualTo (0.0f), "ContentAverageLightLevel B"); + Assert.That (copy.CalculatedContentAverageLightLevel, Is.Not.EqualTo (0.0f), "CalculatedContentAverageLightLevel B"); + + using var copy2 = img.CopyWithContentAverageLightLevel (0.75f); + Assert.That (copy2.CalculatedContentHeadroom, Is.EqualTo (0.0f), "CalculatedContentHeadroom C"); + Assert.That (copy2.ContentAverageLightLevel, Is.Not.EqualTo (0.0f), "ContentAverageLightLevel C"); + Assert.That (copy2.CalculatedContentAverageLightLevel, Is.Not.EqualTo (0.0f), "CalculatedContentAverageLightLevel C"); + + using var copy3 = img.CopyWithCalculatedHdrStats (); + Assert.That (copy3.CalculatedContentHeadroom, Is.EqualTo (0.0f), "CalculatedContentHeadroom D"); + Assert.That (copy3.ContentAverageLightLevel, Is.Not.EqualTo (0.0f), "ContentAverageLightLevel D"); + Assert.That (copy3.CalculatedContentAverageLightLevel, Is.Not.EqualTo (0.0f), "CalculatedContentAverageLightLevel D"); + } }); } } diff --git a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs new file mode 100644 index 000000000000..4f0ea26cb1c9 --- /dev/null +++ b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using Foundation; +using CoreGraphics; +using NUnit.Framework; + +namespace MonoTouchFixtures.CoreGraphics { + + [TestFixture] + [Preserve (AllMembers = true)] + public class CGRenderingBufferProviderTest { + // FIXME: improve these tests + + [Test] + public void CreateWithCFData_ReturnsInstanceOrNull() + { + var data = new NSMutableData(10); // Create a small CFMutableDataRef + var provider = CGRenderingBufferProvider.Create(data); + Assert.That(provider, Is.Null.Or.InstanceOf(), "Should return null or a valid instance"); + } + + [Test] + public void SizeProperty_DoesNotThrow() + { + var data = new NSMutableData(10); + var provider = CGRenderingBufferProvider.Create(data); + if (provider != null) + { + Assert.DoesNotThrow(() => { var size = provider.Size; }); + } + } + + [Test] + public void LockUnlockBytePointer_DoesNotThrow() + { + var data = new NSMutableData(10); + var provider = CGRenderingBufferProvider.Create(data); + if (provider != null) + { + Assert.DoesNotThrow(() => { + var ptr = provider.LockBytePointer(); + provider.UnlockBytePointer(); + }); + } + } + + [Test] + public void GetTypeId_ReturnsTypeId() + { + Assert.DoesNotThrow(() => { + var typeId = CGRenderingBufferProvider.GetTypeId(); + Assert.GreaterOrEqual(typeId, 0); + }); + } + } +} diff --git a/tests/monotouch-test/CoreGraphics/CGToneMappingOptionsTest.cs b/tests/monotouch-test/CoreGraphics/CGToneMappingOptionsTest.cs new file mode 100644 index 000000000000..15a11ca20875 --- /dev/null +++ b/tests/monotouch-test/CoreGraphics/CGToneMappingOptionsTest.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; + +using Foundation; +using CoreGraphics; +using ObjCRuntime; + +using NUnit.Framework; + +namespace MonoTouchFixtures.CoreGraphics { + + [TestFixture] + [Preserve (AllMembers = true)] + public class CGToneMappingOptionsTest { + [Test] + public void DefaultOptions () + { + TestRuntime.AssertXcodeVersion (26, 0); + + var defaultOptions = CGToneMappingOptions.GetDefaultExrToneMappingGammaOptions (); + Assert.That (defaultOptions, Is.Not.Null, "Default"); + } + } +} diff --git a/tests/monotouch-test/CoreGraphics/ColorTest.cs b/tests/monotouch-test/CoreGraphics/ColorTest.cs index 247e0995341e..70f5fc5d7841 100644 --- a/tests/monotouch-test/CoreGraphics/ColorTest.cs +++ b/tests/monotouch-test/CoreGraphics/ColorTest.cs @@ -121,5 +121,24 @@ public void CreateByMatchingToColorSpace () Assert.IsNotNull (c2, "2"); } } + + [Test] + public void ContentHeadroom () + { + TestRuntime.AssertXcodeVersion (26, 0); + + using (var color = CGColor.CreateWithContentHeadroom (0.5f, null, 0.3f, 0.4f, 0.5f, 0.6f)) { + Assert.IsNull (color, "color #1"); + } + + using var headroomCapableColorspace = CGColorSpace.CreateWithName (CGColorSpaceNames.ExtendedSrgb); + using (var color = CGColor.CreateWithContentHeadroom (0.0f, headroomCapableColorspace, 0.3f, 0.4f, 0.5f, 0.6f)) { + Assert.IsNotNull (color, "color #2"); + Assert.That (color.ContentHeadroom, Is.EqualTo (0.0f), "ContentHeadroom #2"); + Assert.That (color.NumberOfComponents, Is.EqualTo ((nint) 4), "NumberOfComponents #2"); + Assert.That (color.Components, Is.EqualTo (new nfloat [] { 0.3f, 0.4f, 0.5f, 0.6f }), "Components #2"); + Assert.That (color.Alpha, Is.EqualTo ((nfloat) 0.6f), "Alpha #2"); + } + } } } diff --git a/tests/monotouch-test/CoreGraphics/FunctionTest.cs b/tests/monotouch-test/CoreGraphics/FunctionTest.cs index 7dfbe854e88a..acddc6a49922 100644 --- a/tests/monotouch-test/CoreGraphics/FunctionTest.cs +++ b/tests/monotouch-test/CoreGraphics/FunctionTest.cs @@ -9,6 +9,8 @@ #if !MONOMAC using System; +using System.Collections.Generic; + using Foundation; using CoreGraphics; using UIKit; @@ -43,31 +45,52 @@ public unsafe override void Draw (CGRect rect) var start = new CGPoint (rect.Left, rect.Bottom); var end = new CGPoint (rect.Left, rect.Top); - var domain = new nfloat [] { 0f, 1f }; - var range = new nfloat [] { 0f, 1f, 0f, 1f }; using (var context = UIGraphics.GetCurrentContext ()) using (var rgb = CGColorSpace.CreateDeviceGray ()) - using (var shadingFunction = new CGFunction (domain, range, Shading)) + using (var shadingFunction = CreateSlopedFunction (Shaded)) using (var shading = CGShading.CreateAxial (rgb, start, end, shadingFunction, true, false)) { context.DrawShading (shading); } base.Draw (rect); } + } - public unsafe void Shading (nfloat* data, nfloat* outData) - { - var p = data [0]; - outData [0] = 0.0f; - outData [1] = (1.0f - Slope (p, 2.0f)) * 0.5f; - Shaded (); + public unsafe static CGFunction CreateSlopedFunction (Action? shadedCallback, nint inputs = 1, nint outputs = 2) + { + if (inputs < 1 || outputs < 1) + throw new ArgumentOutOfRangeException (); + + var domain = new List (); + for (var i = 0; i < inputs; i++) { + domain.Add (0); + domain.Add (1); } + var range = new List (); + for (var i = 0; i < outputs; i++) { + range.Add (0); + range.Add (1); + } + return new CGFunction (domain.ToArray (), range.ToArray (), Shading); - public nfloat Slope (nfloat x, nfloat A) + nfloat Slope (nfloat x, nfloat A) { var p = Math.Pow (x, A); return (nfloat) (p / (p + Math.Pow (1.0f - x, A))); } + + void Shading (nfloat* data, nfloat* outData) + { + outData [0] = 0.0f; + for (var x = 0; x < inputs; x++) { + var p = data [x]; + for (var y = 1; y < outputs; y++) { + outData [y] = (1.0f - Slope (p, 2.0f)) * (1.0f / outputs) * y; + } + } + if (shadedCallback is not null) + shadedCallback (); + } } [Test] diff --git a/tests/monotouch-test/CoreGraphics/GradientTest.cs b/tests/monotouch-test/CoreGraphics/GradientTest.cs index 739beb03f9df..36a220fc181d 100644 --- a/tests/monotouch-test/CoreGraphics/GradientTest.cs +++ b/tests/monotouch-test/CoreGraphics/GradientTest.cs @@ -92,5 +92,33 @@ public void GradientDrawingOptions () // this would be "3" without a [Flags] attribute Assert.That (gdo.ToString (), Is.EqualTo ("DrawsBeforeStartLocation, DrawsAfterEndLocation"), "ToString/Flags"); } + + [Test] + public void CreateWithHeadroom () + { + TestRuntime.AssertXcodeVersion (26, 0); + + var colorComponents = new nfloat [] { + 0.1f, 0.2f, 0.3f, + 0.4f, 0.5f, 0.6f, + 0.7f, 0.8f, 0.9f, + }; + var locations = new nfloat [] { + 0, + 0.25f, + 1, + }; + + using var hdrCapableColorspace = CGColorSpace.CreateWithName (CGColorSpaceNames.DisplayP3_PQ); + Assert.IsTrue (hdrCapableColorspace.IsHdr, "IsHdr"); + using (var gradient = CGGradient.Create (0.5f, hdrCapableColorspace, colorComponents, locations)) { + Assert.IsNotNull (gradient, "Gradient #1"); + Assert.That (gradient.ContentHeadroom, Is.EqualTo (1.0f), "Gradient #1 - ContentHeadroom"); + } + + using (var gradient = CGGradient.Create (0.5f, null, colorComponents, locations)) { + Assert.IsNull (gradient, "Gradient #2"); + } + } } } diff --git a/tests/monotouch-test/CoreGraphics/ShadingTest.cs b/tests/monotouch-test/CoreGraphics/ShadingTest.cs new file mode 100644 index 000000000000..3ddc232d8641 --- /dev/null +++ b/tests/monotouch-test/CoreGraphics/ShadingTest.cs @@ -0,0 +1,83 @@ +// +// Unit tests for CGPath +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2013-2014 Xamarin Inc. All rights reserved. +// + +using System; +using System.IO; +using System.Runtime.InteropServices; +using Foundation; +using CoreGraphics; +using ObjCRuntime; +using NUnit.Framework; + +#if HAS_UIKIT +using UIKit; +#endif + +namespace MonoTouchFixtures.CoreGraphics { + + [TestFixture] + [Preserve (AllMembers = true)] + public class CGShadingTest { +#if HAS_UIKIT + [Test] + public void CreateAxialWithContentHeadroom () + { + CreateShadingWithContentHeadroomTest ((size, hdrCapableColorspace, function) => { + var start = new CGPoint (0, 0); + var end = new CGPoint (size.Height, size.Width); + + return CGShading.CreateAxial (0.5f, hdrCapableColorspace, start, end, function, true, false); + }); + + TestRuntime.AssertXcodeVersion (26, 0); + } + + [Test] + public void CreateRadialWithContentHeadroom () + { + CreateShadingWithContentHeadroomTest ((size, hdrCapableColorspace, function) => { + var start = new CGPoint (0, 0); + var startRadius = 16.0f; + var end = new CGPoint (size.Height, size.Width); + var endRadius = 32.0f; + + return CGShading.CreateRadial (0.5f, hdrCapableColorspace, start, startRadius, end, endRadius, function, true, false); + }); + } + + void CreateShadingWithContentHeadroomTest (Func createShading) + { + TestRuntime.AssertXcodeVersion (26, 0); + + var size = new CGSize (128, 128); + var functionCalled = false; + Exception? ex = null; + + using var renderer = new UIGraphicsImageRenderer (size); + using var img = renderer.CreateImage ((context) => + { + try { + using var hdrCapableColorspace = CGColorSpace.CreateWithName (CGColorSpaceNames.DisplayP3_PQ); + Assert.IsTrue (hdrCapableColorspace.IsHdr, "IsHdr"); + + using var slopedFunction = FunctionTest.CreateSlopedFunction (() => functionCalled = true, 1, hdrCapableColorspace.Components + 1); + + using var shading = createShading (size, hdrCapableColorspace, slopedFunction); + context.CGContext.DrawShading (shading); + } catch (Exception e) { + ex = e; + } + }); + + Assert.IsTrue (functionCalled, "Function called"); + Assert.IsNull (ex, "Exception"); + } +#endif + } +} diff --git a/tests/monotouch-test/GlobalUsings.cs b/tests/monotouch-test/GlobalUsings.cs new file mode 100644 index 000000000000..d833e9fc27ec --- /dev/null +++ b/tests/monotouch-test/GlobalUsings.cs @@ -0,0 +1,6 @@ +global using System; + +global using Foundation; +global using ObjCRuntime; + +global using NUnit.Framework; diff --git a/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-CoreGraphics.todo b/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-CoreGraphics.todo deleted file mode 100644 index 8e8e0f1ee6cd..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-CoreGraphics.todo +++ /dev/null @@ -1,34 +0,0 @@ -!missing-enum! CGBitmapLayout not bound -!missing-enum! CGColorModel not bound -!missing-enum! CGComponent not bound -!missing-enum! CGImageComponentInfo not bound -!missing-field! kCGAdaptiveMaximumBitDepth not bound -!missing-field! kCGContentAverageLightLevel not bound -!missing-field! kCGContentAverageLightLevelNits not bound -!missing-field! kCGDynamicRangeConstrained not bound -!missing-field! kCGDynamicRangeHigh not bound -!missing-field! kCGDynamicRangeStandard not bound -!missing-field! kCGPreferredDynamicRange not bound -!missing-pinvoke! CGBitmapContextCreateAdaptive is not bound -!missing-pinvoke! CGColorCreateWithContentHeadroom is not bound -!missing-pinvoke! CGColorGetContentHeadroom is not bound -!missing-pinvoke! CGContextGetContentToneMappingInfo is not bound -!missing-pinvoke! CGContextSetContentToneMappingInfo is not bound -!missing-pinvoke! CGContextSynchronizeAttributes is not bound -!missing-pinvoke! CGEXRToneMappingGammaGetDefaultOptions is not bound -!missing-pinvoke! CGImageCalculateContentAverageLightLevel is not bound -!missing-pinvoke! CGImageCalculateContentHeadroom is not bound -!missing-pinvoke! CGImageCreateCopyWithCalculatedHDRStats is not bound -!missing-pinvoke! CGImageCreateCopyWithContentAverageLightLevel is not bound -!missing-pinvoke! CGImageGetContentAverageLightLevel is not bound -!missing-pinvoke! CGRenderingBufferLockBytePtr is not bound -!missing-pinvoke! CGRenderingBufferProviderCreate is not bound -!missing-pinvoke! CGRenderingBufferProviderCreateWithCFData is not bound -!missing-pinvoke! CGRenderingBufferProviderGetSize is not bound -!missing-pinvoke! CGRenderingBufferProviderGetTypeID is not bound -!missing-pinvoke! CGRenderingBufferUnlockBytePtr is not bound -!missing-pinvoke! CGGradientCreateWithContentHeadroom is not bound -!missing-pinvoke! CGGradientGetContentHeadroom is not bound -!missing-pinvoke! CGShadingCreateAxialWithContentHeadroom is not bound -!missing-pinvoke! CGShadingCreateRadialWithContentHeadroom is not bound -!missing-pinvoke! CGShadingGetContentHeadroom is not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/common-CoreFoundation.ignore b/tests/xtro-sharpie/api-annotations-dotnet/common-CoreFoundation.ignore index 63cf707b6bc0..f18340336cbb 100644 --- a/tests/xtro-sharpie/api-annotations-dotnet/common-CoreFoundation.ignore +++ b/tests/xtro-sharpie/api-annotations-dotnet/common-CoreFoundation.ignore @@ -78,9 +78,12 @@ !missing-pinvoke! CFAllocatorReallocateTyped is not bound !missing-pinvoke! CFAllocatorSetDefault is not bound +## We've named the CFByteOrder enum slightly differently than it shows up in the headers +!missing-enum! __CFByteOrder not bound +!unknown-native-enum! CFByteOrder bound + ## unsorted -!missing-enum! __CFByteOrder not bound !missing-enum! CFCalendarUnit not bound !missing-enum! CFCharacterSetPredefinedSet not bound !missing-enum! CFDataSearchFlags not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/common-CoreGraphics.ignore b/tests/xtro-sharpie/api-annotations-dotnet/common-CoreGraphics.ignore index a32969807625..08b2f0b58160 100644 --- a/tests/xtro-sharpie/api-annotations-dotnet/common-CoreGraphics.ignore +++ b/tests/xtro-sharpie/api-annotations-dotnet/common-CoreGraphics.ignore @@ -12,7 +12,6 @@ ## unsorted -!missing-enum! CGBitmapInfo not bound !missing-enum! CGError not bound !missing-enum! CGFontPostScriptFormat not bound !missing-field! CGAffineTransformIdentity not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/iOS-CoreGraphics.todo b/tests/xtro-sharpie/api-annotations-dotnet/iOS-CoreGraphics.todo deleted file mode 100644 index 8e8e0f1ee6cd..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/iOS-CoreGraphics.todo +++ /dev/null @@ -1,34 +0,0 @@ -!missing-enum! CGBitmapLayout not bound -!missing-enum! CGColorModel not bound -!missing-enum! CGComponent not bound -!missing-enum! CGImageComponentInfo not bound -!missing-field! kCGAdaptiveMaximumBitDepth not bound -!missing-field! kCGContentAverageLightLevel not bound -!missing-field! kCGContentAverageLightLevelNits not bound -!missing-field! kCGDynamicRangeConstrained not bound -!missing-field! kCGDynamicRangeHigh not bound -!missing-field! kCGDynamicRangeStandard not bound -!missing-field! kCGPreferredDynamicRange not bound -!missing-pinvoke! CGBitmapContextCreateAdaptive is not bound -!missing-pinvoke! CGColorCreateWithContentHeadroom is not bound -!missing-pinvoke! CGColorGetContentHeadroom is not bound -!missing-pinvoke! CGContextGetContentToneMappingInfo is not bound -!missing-pinvoke! CGContextSetContentToneMappingInfo is not bound -!missing-pinvoke! CGContextSynchronizeAttributes is not bound -!missing-pinvoke! CGEXRToneMappingGammaGetDefaultOptions is not bound -!missing-pinvoke! CGImageCalculateContentAverageLightLevel is not bound -!missing-pinvoke! CGImageCalculateContentHeadroom is not bound -!missing-pinvoke! CGImageCreateCopyWithCalculatedHDRStats is not bound -!missing-pinvoke! CGImageCreateCopyWithContentAverageLightLevel is not bound -!missing-pinvoke! CGImageGetContentAverageLightLevel is not bound -!missing-pinvoke! CGRenderingBufferLockBytePtr is not bound -!missing-pinvoke! CGRenderingBufferProviderCreate is not bound -!missing-pinvoke! CGRenderingBufferProviderCreateWithCFData is not bound -!missing-pinvoke! CGRenderingBufferProviderGetSize is not bound -!missing-pinvoke! CGRenderingBufferProviderGetTypeID is not bound -!missing-pinvoke! CGRenderingBufferUnlockBytePtr is not bound -!missing-pinvoke! CGGradientCreateWithContentHeadroom is not bound -!missing-pinvoke! CGGradientGetContentHeadroom is not bound -!missing-pinvoke! CGShadingCreateAxialWithContentHeadroom is not bound -!missing-pinvoke! CGShadingCreateRadialWithContentHeadroom is not bound -!missing-pinvoke! CGShadingGetContentHeadroom is not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/macOS-CoreGraphics.todo b/tests/xtro-sharpie/api-annotations-dotnet/macOS-CoreGraphics.todo deleted file mode 100644 index 8e8e0f1ee6cd..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/macOS-CoreGraphics.todo +++ /dev/null @@ -1,34 +0,0 @@ -!missing-enum! CGBitmapLayout not bound -!missing-enum! CGColorModel not bound -!missing-enum! CGComponent not bound -!missing-enum! CGImageComponentInfo not bound -!missing-field! kCGAdaptiveMaximumBitDepth not bound -!missing-field! kCGContentAverageLightLevel not bound -!missing-field! kCGContentAverageLightLevelNits not bound -!missing-field! kCGDynamicRangeConstrained not bound -!missing-field! kCGDynamicRangeHigh not bound -!missing-field! kCGDynamicRangeStandard not bound -!missing-field! kCGPreferredDynamicRange not bound -!missing-pinvoke! CGBitmapContextCreateAdaptive is not bound -!missing-pinvoke! CGColorCreateWithContentHeadroom is not bound -!missing-pinvoke! CGColorGetContentHeadroom is not bound -!missing-pinvoke! CGContextGetContentToneMappingInfo is not bound -!missing-pinvoke! CGContextSetContentToneMappingInfo is not bound -!missing-pinvoke! CGContextSynchronizeAttributes is not bound -!missing-pinvoke! CGEXRToneMappingGammaGetDefaultOptions is not bound -!missing-pinvoke! CGImageCalculateContentAverageLightLevel is not bound -!missing-pinvoke! CGImageCalculateContentHeadroom is not bound -!missing-pinvoke! CGImageCreateCopyWithCalculatedHDRStats is not bound -!missing-pinvoke! CGImageCreateCopyWithContentAverageLightLevel is not bound -!missing-pinvoke! CGImageGetContentAverageLightLevel is not bound -!missing-pinvoke! CGRenderingBufferLockBytePtr is not bound -!missing-pinvoke! CGRenderingBufferProviderCreate is not bound -!missing-pinvoke! CGRenderingBufferProviderCreateWithCFData is not bound -!missing-pinvoke! CGRenderingBufferProviderGetSize is not bound -!missing-pinvoke! CGRenderingBufferProviderGetTypeID is not bound -!missing-pinvoke! CGRenderingBufferUnlockBytePtr is not bound -!missing-pinvoke! CGGradientCreateWithContentHeadroom is not bound -!missing-pinvoke! CGGradientGetContentHeadroom is not bound -!missing-pinvoke! CGShadingCreateAxialWithContentHeadroom is not bound -!missing-pinvoke! CGShadingCreateRadialWithContentHeadroom is not bound -!missing-pinvoke! CGShadingGetContentHeadroom is not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/tvOS-CoreGraphics.todo b/tests/xtro-sharpie/api-annotations-dotnet/tvOS-CoreGraphics.todo deleted file mode 100644 index 8e8e0f1ee6cd..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/tvOS-CoreGraphics.todo +++ /dev/null @@ -1,34 +0,0 @@ -!missing-enum! CGBitmapLayout not bound -!missing-enum! CGColorModel not bound -!missing-enum! CGComponent not bound -!missing-enum! CGImageComponentInfo not bound -!missing-field! kCGAdaptiveMaximumBitDepth not bound -!missing-field! kCGContentAverageLightLevel not bound -!missing-field! kCGContentAverageLightLevelNits not bound -!missing-field! kCGDynamicRangeConstrained not bound -!missing-field! kCGDynamicRangeHigh not bound -!missing-field! kCGDynamicRangeStandard not bound -!missing-field! kCGPreferredDynamicRange not bound -!missing-pinvoke! CGBitmapContextCreateAdaptive is not bound -!missing-pinvoke! CGColorCreateWithContentHeadroom is not bound -!missing-pinvoke! CGColorGetContentHeadroom is not bound -!missing-pinvoke! CGContextGetContentToneMappingInfo is not bound -!missing-pinvoke! CGContextSetContentToneMappingInfo is not bound -!missing-pinvoke! CGContextSynchronizeAttributes is not bound -!missing-pinvoke! CGEXRToneMappingGammaGetDefaultOptions is not bound -!missing-pinvoke! CGImageCalculateContentAverageLightLevel is not bound -!missing-pinvoke! CGImageCalculateContentHeadroom is not bound -!missing-pinvoke! CGImageCreateCopyWithCalculatedHDRStats is not bound -!missing-pinvoke! CGImageCreateCopyWithContentAverageLightLevel is not bound -!missing-pinvoke! CGImageGetContentAverageLightLevel is not bound -!missing-pinvoke! CGRenderingBufferLockBytePtr is not bound -!missing-pinvoke! CGRenderingBufferProviderCreate is not bound -!missing-pinvoke! CGRenderingBufferProviderCreateWithCFData is not bound -!missing-pinvoke! CGRenderingBufferProviderGetSize is not bound -!missing-pinvoke! CGRenderingBufferProviderGetTypeID is not bound -!missing-pinvoke! CGRenderingBufferUnlockBytePtr is not bound -!missing-pinvoke! CGGradientCreateWithContentHeadroom is not bound -!missing-pinvoke! CGGradientGetContentHeadroom is not bound -!missing-pinvoke! CGShadingCreateAxialWithContentHeadroom is not bound -!missing-pinvoke! CGShadingCreateRadialWithContentHeadroom is not bound -!missing-pinvoke! CGShadingGetContentHeadroom is not bound From c2b24bfdcf1bf193b257417488c19d170c41c629 Mon Sep 17 00:00:00 2001 From: GitHub Actions Autoformatter Date: Wed, 20 Aug 2025 18:05:44 +0000 Subject: [PATCH 2/7] Auto-format source code --- src/CoreGraphics/CGContentToneMappingInfo.cs | 3 +- src/CoreGraphics/CGGradient.cs | 2 +- src/CoreGraphics/CGRenderingBufferProvider.cs | 12 +++--- src/CoreGraphics/CGShading.cs | 2 +- src/coregraphics.cs | 21 ++++------ .../CoreGraphics/BitmapContextTest.cs | 9 ++-- .../CoreGraphics/CGBitmapParametersTest.cs | 20 ++++----- .../CoreGraphics/CGContentInfoTest.cs | 12 +++--- .../CGRenderingBufferProviderTest.cs | 42 +++++++++---------- .../CoreGraphics/ShadingTest.cs | 3 +- 10 files changed, 57 insertions(+), 69 deletions(-) diff --git a/src/CoreGraphics/CGContentToneMappingInfo.cs b/src/CoreGraphics/CGContentToneMappingInfo.cs index 907887ccf13b..75f2e576ce26 100644 --- a/src/CoreGraphics/CGContentToneMappingInfo.cs +++ b/src/CoreGraphics/CGContentToneMappingInfo.cs @@ -10,8 +10,7 @@ namespace CoreGraphics { [SupportedOSPlatform ("maccatalyst26.0")] [SupportedOSPlatform ("macos26.0")] [StructLayout (LayoutKind.Sequential)] - public struct CGContentToneMappingInfo - { + public struct CGContentToneMappingInfo { CGToneMapping method; IntPtr /* CFDictionaryRef __nullable */ options; diff --git a/src/CoreGraphics/CGGradient.cs b/src/CoreGraphics/CGGradient.cs index 85196286e870..425020bd8507 100644 --- a/src/CoreGraphics/CGGradient.cs +++ b/src/CoreGraphics/CGGradient.cs @@ -223,7 +223,7 @@ public CGGradient (CGColorSpace? colorspace, CGColor [] colors) [SupportedOSPlatform ("tvos26.0")] [SupportedOSPlatform ("maccatalyst26.0")] [SupportedOSPlatform ("macos26.0")] - public static CGGradient? Create (float headroom, CGColorSpace? colorSpace, nfloat[]? components, nfloat[]? locations) + public static CGGradient? Create (float headroom, CGColorSpace? colorSpace, nfloat []? components, nfloat []? locations) { // "The number of locations is specified by `count'" // "The number of color components is the product of `count' and the number of color components of `space'." diff --git a/src/CoreGraphics/CGRenderingBufferProvider.cs b/src/CoreGraphics/CGRenderingBufferProvider.cs index ad647e684c9f..1c3c5e0f556d 100644 --- a/src/CoreGraphics/CGRenderingBufferProvider.cs +++ b/src/CoreGraphics/CGRenderingBufferProvider.cs @@ -38,13 +38,13 @@ internal CGRenderingBufferProvider (NativeHandle handle, bool owns) if (lockPointer is null) ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (lockPointer)); - delegate* unmanaged lockPointerTrampoline = &LockPointerBlock; + delegate* unmanaged lockPointerTrampoline = &LockPointerBlock; using var lockPointerBlock = new BlockLiteral (lockPointerTrampoline, lockPointer, typeof (CGRenderingBufferProvider), nameof (LockPointerBlock)); - delegate* unmanaged unlockPointerTrampoline = &UnlockPointerBlock; + delegate* unmanaged unlockPointerTrampoline = &UnlockPointerBlock; using var unlockPointerBlock = unlockPointer is null ? default (BlockLiteral) : new BlockLiteral (unlockPointerTrampoline, unlockPointer, typeof (CGRenderingBufferProvider), nameof (UnlockPointerBlock)); - delegate* unmanaged releaseInfoTrampoline = &ReleaseInfoBlock; + delegate* unmanaged releaseInfoTrampoline = &ReleaseInfoBlock; using var releaseInfoBlock = releaseInfo is null ? default (BlockLiteral) : new BlockLiteral (releaseInfoTrampoline, releaseInfo, typeof (CGRenderingBufferProvider), nameof (ReleaseInfoBlock)); var h = CGRenderingBufferProviderCreate ( @@ -61,7 +61,7 @@ internal CGRenderingBufferProvider (NativeHandle handle, bool owns) public delegate IntPtr LockPointerCallback (IntPtr info); [UnmanagedCallersOnly] - unsafe static IntPtr LockPointerBlock (BlockLiteral *block, IntPtr info) + unsafe static IntPtr LockPointerBlock (BlockLiteral* block, IntPtr info) { var del = BlockLiteral.GetTarget ((IntPtr) block); if (del is not null) @@ -72,7 +72,7 @@ unsafe static IntPtr LockPointerBlock (BlockLiteral *block, IntPtr info) public delegate void UnlockPointerCallback (IntPtr info, IntPtr pointer); [UnmanagedCallersOnly] - unsafe static void UnlockPointerBlock (BlockLiteral *block, IntPtr info, IntPtr pointer) + unsafe static void UnlockPointerBlock (BlockLiteral* block, IntPtr info, IntPtr pointer) { var del = BlockLiteral.GetTarget ((IntPtr) block); if (del is not null) @@ -82,7 +82,7 @@ unsafe static void UnlockPointerBlock (BlockLiteral *block, IntPtr info, IntPtr public delegate void ReleaseInfoCallback (IntPtr info); [UnmanagedCallersOnly] - unsafe static void ReleaseInfoBlock (BlockLiteral *block, IntPtr info) + unsafe static void ReleaseInfoBlock (BlockLiteral* block, IntPtr info) { var del = BlockLiteral.GetTarget ((IntPtr) block); if (del is not null) diff --git a/src/CoreGraphics/CGShading.cs b/src/CoreGraphics/CGShading.cs index 5d855e59190e..cb088db995c0 100644 --- a/src/CoreGraphics/CGShading.cs +++ b/src/CoreGraphics/CGShading.cs @@ -102,7 +102,7 @@ protected internal override void Release () public static CGShading? CreateRadial (CGColorSpace? colorspace, CGPoint start, nfloat startRadius, CGPoint end, nfloat endRadius, CGFunction? function, bool extendStart, bool extendEnd) { - var handle =CGShadingCreateRadial (colorspace.GetHandle (), start, startRadius, end, endRadius, + var handle = CGShadingCreateRadial (colorspace.GetHandle (), start, startRadius, end, endRadius, function.GetHandle (), extendStart.AsByte (), extendEnd.AsByte ()); GC.KeepAlive (colorspace); GC.KeepAlive (function); diff --git a/src/coregraphics.cs b/src/coregraphics.cs index 0f317531dcf8..51c045096a44 100644 --- a/src/coregraphics.cs +++ b/src/coregraphics.cs @@ -679,8 +679,7 @@ interface CoreGraphicsFields { [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] [Flags] - public enum CGColorModel : uint - { + public enum CGColorModel : uint { NoColorant = 0u << 0, Gray = 1u << 0, Rgb = 1u << 1, @@ -690,8 +689,7 @@ public enum CGColorModel : uint } [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] - public enum CGComponent : uint - { + public enum CGComponent : uint { Unknown = 0, Integer8Bit = 1, Integer10Bit = 6, @@ -702,8 +700,7 @@ public enum CGComponent : uint } [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] - public enum CGBitmapLayout : uint - { + public enum CGBitmapLayout : uint { AlphaOnly, Gray, GrayAlpha, @@ -719,8 +716,7 @@ public enum CGBitmapLayout : uint } [Partial] - interface CGAdaptiveKeys - { + interface CGAdaptiveKeys { [Field ("kCGAdaptiveMaximumBitDepth")] NSString MaximumBitDepthKey { get; } } @@ -730,17 +726,16 @@ interface CGAdaptiveOptions { CGComponent MaximumBitDepth { get; set; } } - public enum CGImageComponentInfo : uint - { + public enum CGImageComponentInfo : uint { Integer = (0u << 8), Float = (1u << 8), } [Flags] public enum CGBitmapInfo : uint { - AlphaInfoMask = 0x1F, - ComponentInfoMask = 0xF00, - ByteOrderInfoMask = 0x7000, + AlphaInfoMask = 0x1F, + ComponentInfoMask = 0xF00, + ByteOrderInfoMask = 0x7000, PixelFormatInfoMask = 0xF0000, } diff --git a/tests/monotouch-test/CoreGraphics/BitmapContextTest.cs b/tests/monotouch-test/CoreGraphics/BitmapContextTest.cs index 59cae7b36e81..6f237c5d8ccb 100644 --- a/tests/monotouch-test/CoreGraphics/BitmapContextTest.cs +++ b/tests/monotouch-test/CoreGraphics/BitmapContextTest.cs @@ -132,8 +132,7 @@ public void CreateAdaptive () var calledOnFree = false; var calledOnError = false; using var context = CGBitmapContext.Create (width, height, (CGAdaptiveOptions?) null, - (ref CGContentInfo info, ref CGBitmapParameters parameters) => - { + (ref CGContentInfo info, ref CGBitmapParameters parameters) => { Console.WriteLine ($"CreateAdaptive () OnResolve#2 info={info} parameters={parameters}"); calledOnResolve = true; return true; @@ -173,8 +172,7 @@ public void CreateAdaptive () MaximumBitDepth = CGComponent.Float16Bit, }; using var context = CGBitmapContext.Create (width, height, options, - (ref CGContentInfo info, ref CGBitmapParameters parameters) => - { + (ref CGContentInfo info, ref CGBitmapParameters parameters) => { Console.WriteLine ($"CreateAdaptive () OnResolve#3 info={info} parameters={parameters}"); calledOnResolve = true; return true; @@ -239,8 +237,7 @@ public void CreateAdaptive () }; using (var context = CGBitmapContext.Create (width, height, options, - (ref CGContentInfo info, ref CGBitmapParameters parameters) => - { + (ref CGContentInfo info, ref CGBitmapParameters parameters) => { // Console.WriteLine ($"CreateAdaptive () OnResolve#4 info={info} parameters={parameters}"); calledOnResolve = true; return true; diff --git a/tests/monotouch-test/CoreGraphics/CGBitmapParametersTest.cs b/tests/monotouch-test/CoreGraphics/CGBitmapParametersTest.cs index 94b95e0db713..8cb40d127e82 100644 --- a/tests/monotouch-test/CoreGraphics/CGBitmapParametersTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGBitmapParametersTest.cs @@ -20,12 +20,12 @@ public void DefaultValuesTest () Assert.AreEqual ((nuint) 0u, p.Height, "Height"); Assert.AreEqual ((nuint) 0u, p.BytesPerPixel, "BytesPerPixel"); Assert.AreEqual ((nuint) 0u, p.AlignedBytesPerRow, "AlignedBytesPerRow"); - Assert.AreEqual (default(CGComponent), p.Component, "Component"); - Assert.AreEqual (default(CGBitmapLayout), p.Layout, "Layout"); - Assert.AreEqual (default(CGImagePixelFormatInfo), p.Format, "Format"); + Assert.AreEqual (default (CGComponent), p.Component, "Component"); + Assert.AreEqual (default (CGBitmapLayout), p.Layout, "Layout"); + Assert.AreEqual (default (CGImagePixelFormatInfo), p.Format, "Format"); Assert.AreEqual (IntPtr.Zero, p.ColorSpaceHandle, "ColorSpaceHandle"); Assert.AreEqual (false, p.HasPremultipliedAlpha, "HasPremultipliedAlpha"); - Assert.AreEqual ((CFByteOrder)0, p.ByteOrder, "ByteOrder"); + Assert.AreEqual ((CFByteOrder) 0, p.ByteOrder, "ByteOrder"); Assert.AreEqual (0f, p.EdrTargetHeadroom, "EdrTargetHeadroom"); }); } @@ -39,9 +39,9 @@ public void PropertySetGetTest () p.Height = 456u; p.BytesPerPixel = 4u; p.AlignedBytesPerRow = 512u; - p.Component = (CGComponent)1; - p.Layout = (CGBitmapLayout)2; - p.Format = (CGImagePixelFormatInfo)3; + p.Component = (CGComponent) 1; + p.Layout = (CGBitmapLayout) 2; + p.Format = (CGImagePixelFormatInfo) 3; p.ColorSpaceHandle = new IntPtr (0xDEADBEEF); p.HasPremultipliedAlpha = true; p.ByteOrder = CFByteOrder.LittleEndian; @@ -51,9 +51,9 @@ public void PropertySetGetTest () Assert.AreEqual ((nuint) 456u, p.Height, "Height"); Assert.AreEqual ((nuint) 4u, p.BytesPerPixel, "BytesPerPixel"); Assert.AreEqual ((nuint) 512u, p.AlignedBytesPerRow, "AlignedBytesPerRow"); - Assert.AreEqual ((CGComponent)1, p.Component, "Component"); - Assert.AreEqual ((CGBitmapLayout)2, p.Layout, "Layout"); - Assert.AreEqual ((CGImagePixelFormatInfo)3, p.Format, "Format"); + Assert.AreEqual ((CGComponent) 1, p.Component, "Component"); + Assert.AreEqual ((CGBitmapLayout) 2, p.Layout, "Layout"); + Assert.AreEqual ((CGImagePixelFormatInfo) 3, p.Format, "Format"); Assert.AreEqual (new IntPtr (0xDEADBEEF), p.ColorSpaceHandle, "ColorSpaceHandle"); Assert.IsTrue (p.HasPremultipliedAlpha, "HasPremultipliedAlpha"); Assert.AreEqual (CFByteOrder.LittleEndian, p.ByteOrder, "ByteOrder"); diff --git a/tests/monotouch-test/CoreGraphics/CGContentInfoTest.cs b/tests/monotouch-test/CoreGraphics/CGContentInfoTest.cs index c50df8af5275..0e0416e93e00 100644 --- a/tests/monotouch-test/CoreGraphics/CGContentInfoTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGContentInfoTest.cs @@ -15,8 +15,8 @@ public class CGContentInfoTest { public void DefaultValuesTest () { var c = new CGContentInfo (); - Assert.AreEqual (default(CGComponent), c.DeepestImageComponent, "DeepestImageComponent"); - Assert.AreEqual (default(CGColorModel), c.ContentColorModels, "ContentColorModels"); + Assert.AreEqual (default (CGComponent), c.DeepestImageComponent, "DeepestImageComponent"); + Assert.AreEqual (default (CGColorModel), c.ContentColorModels, "ContentColorModels"); Assert.IsFalse (c.HasWideGamut, "HasWideGamut"); Assert.IsFalse (c.HasTransparency, "HasTransparency"); Assert.AreEqual (0f, c.LargestContentHeadroom, "LargestContentHeadroom"); @@ -26,14 +26,14 @@ public void DefaultValuesTest () public void PropertySetGetTest () { var c = new CGContentInfo (); - c.DeepestImageComponent = (CGComponent)2; - c.ContentColorModels = (CGColorModel)3; + c.DeepestImageComponent = (CGComponent) 2; + c.ContentColorModels = (CGColorModel) 3; c.HasWideGamut = true; c.HasTransparency = true; c.LargestContentHeadroom = 1.25f; - Assert.AreEqual ((CGComponent)2, c.DeepestImageComponent, "DeepestImageComponent"); - Assert.AreEqual ((CGColorModel)3, c.ContentColorModels, "ContentColorModels"); + Assert.AreEqual ((CGComponent) 2, c.DeepestImageComponent, "DeepestImageComponent"); + Assert.AreEqual ((CGColorModel) 3, c.ContentColorModels, "ContentColorModels"); Assert.IsTrue (c.HasWideGamut, "HasWideGamut"); Assert.IsTrue (c.HasTransparency, "HasTransparency"); Assert.AreEqual (1.25f, c.LargestContentHeadroom, "LargestContentHeadroom"); diff --git a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs index 4f0ea26cb1c9..b07efba28c1b 100644 --- a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs @@ -14,44 +14,42 @@ public class CGRenderingBufferProviderTest { // FIXME: improve these tests [Test] - public void CreateWithCFData_ReturnsInstanceOrNull() + public void CreateWithCFData_ReturnsInstanceOrNull () { - var data = new NSMutableData(10); // Create a small CFMutableDataRef - var provider = CGRenderingBufferProvider.Create(data); - Assert.That(provider, Is.Null.Or.InstanceOf(), "Should return null or a valid instance"); + var data = new NSMutableData (10); // Create a small CFMutableDataRef + var provider = CGRenderingBufferProvider.Create (data); + Assert.That (provider, Is.Null.Or.InstanceOf (), "Should return null or a valid instance"); } [Test] - public void SizeProperty_DoesNotThrow() + public void SizeProperty_DoesNotThrow () { - var data = new NSMutableData(10); - var provider = CGRenderingBufferProvider.Create(data); - if (provider != null) - { - Assert.DoesNotThrow(() => { var size = provider.Size; }); + var data = new NSMutableData (10); + var provider = CGRenderingBufferProvider.Create (data); + if (provider is not null) { + Assert.DoesNotThrow (() => { var size = provider.Size; }); } } [Test] - public void LockUnlockBytePointer_DoesNotThrow() + public void LockUnlockBytePointer_DoesNotThrow () { - var data = new NSMutableData(10); - var provider = CGRenderingBufferProvider.Create(data); - if (provider != null) - { - Assert.DoesNotThrow(() => { - var ptr = provider.LockBytePointer(); - provider.UnlockBytePointer(); + var data = new NSMutableData (10); + var provider = CGRenderingBufferProvider.Create (data); + if (provider is not null) { + Assert.DoesNotThrow (() => { + var ptr = provider.LockBytePointer (); + provider.UnlockBytePointer (); }); } } [Test] - public void GetTypeId_ReturnsTypeId() + public void GetTypeId_ReturnsTypeId () { - Assert.DoesNotThrow(() => { - var typeId = CGRenderingBufferProvider.GetTypeId(); - Assert.GreaterOrEqual(typeId, 0); + Assert.DoesNotThrow (() => { + var typeId = CGRenderingBufferProvider.GetTypeId (); + Assert.GreaterOrEqual (typeId, 0); }); } } diff --git a/tests/monotouch-test/CoreGraphics/ShadingTest.cs b/tests/monotouch-test/CoreGraphics/ShadingTest.cs index 3ddc232d8641..e0edd9227b03 100644 --- a/tests/monotouch-test/CoreGraphics/ShadingTest.cs +++ b/tests/monotouch-test/CoreGraphics/ShadingTest.cs @@ -60,8 +60,7 @@ void CreateShadingWithContentHeadroomTest (Func - { + using var img = renderer.CreateImage ((context) => { try { using var hdrCapableColorspace = CGColorSpace.CreateWithName (CGColorSpaceNames.DisplayP3_PQ); Assert.IsTrue (hdrCapableColorspace.IsHdr, "IsHdr"); From 8ab7d55627bc12d53a4ce00c8e462f492a098577 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 21 Aug 2025 07:25:26 +0200 Subject: [PATCH 3/7] Fixes --- src/coregraphics.cs | 1 + .../CoreGraphics/CGRenderingBufferProviderTest.cs | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/coregraphics.cs b/src/coregraphics.cs index 51c045096a44..0737f3b3e428 100644 --- a/src/coregraphics.cs +++ b/src/coregraphics.cs @@ -715,6 +715,7 @@ public enum CGBitmapLayout : uint { Cmyk, } + [TV (26, 0), Mac (26, 0), MacCatalyst (26, 0), iOS (26, 0)] [Partial] interface CGAdaptiveKeys { [Field ("kCGAdaptiveMaximumBitDepth")] diff --git a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs index b07efba28c1b..8ba7983018d7 100644 --- a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs @@ -16,6 +16,8 @@ public class CGRenderingBufferProviderTest { [Test] public void CreateWithCFData_ReturnsInstanceOrNull () { + TestRuntime.AssertXcodeVersion (26, 0); + var data = new NSMutableData (10); // Create a small CFMutableDataRef var provider = CGRenderingBufferProvider.Create (data); Assert.That (provider, Is.Null.Or.InstanceOf (), "Should return null or a valid instance"); @@ -24,6 +26,8 @@ public void CreateWithCFData_ReturnsInstanceOrNull () [Test] public void SizeProperty_DoesNotThrow () { + TestRuntime.AssertXcodeVersion (26, 0); + var data = new NSMutableData (10); var provider = CGRenderingBufferProvider.Create (data); if (provider is not null) { @@ -34,6 +38,8 @@ public void SizeProperty_DoesNotThrow () [Test] public void LockUnlockBytePointer_DoesNotThrow () { + TestRuntime.AssertXcodeVersion (26, 0); + var data = new NSMutableData (10); var provider = CGRenderingBufferProvider.Create (data); if (provider is not null) { @@ -47,6 +53,8 @@ public void LockUnlockBytePointer_DoesNotThrow () [Test] public void GetTypeId_ReturnsTypeId () { + TestRuntime.AssertXcodeVersion (26, 0); + Assert.DoesNotThrow (() => { var typeId = CGRenderingBufferProvider.GetTypeId (); Assert.GreaterOrEqual (typeId, 0); From d13e805ffa25b9c38ce8503c94a302dc47e9279d Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 25 Aug 2025 18:44:41 +0200 Subject: [PATCH 4/7] improved tests. --- src/corefoundation.cs | 2 +- .../CGRenderingBufferProviderTest.cs | 52 +++++++++---------- .../CoreGraphics/ShadingTest.cs | 12 +---- 3 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/corefoundation.cs b/src/corefoundation.cs index 1954ff632050..e902b599b143 100644 --- a/src/corefoundation.cs +++ b/src/corefoundation.cs @@ -173,6 +173,6 @@ public enum OSLogLevel : byte { public enum CFByteOrder : long { Unknown, LittleEndian, - BigEndian + BigEndian, } } diff --git a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs index 8ba7983018d7..7fc07c0604bb 100644 --- a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs @@ -11,16 +11,14 @@ namespace MonoTouchFixtures.CoreGraphics { [TestFixture] [Preserve (AllMembers = true)] public class CGRenderingBufferProviderTest { - // FIXME: improve these tests - [Test] - public void CreateWithCFData_ReturnsInstanceOrNull () + public void CreateWithCFData_ReturnsNull () { TestRuntime.AssertXcodeVersion (26, 0); - var data = new NSMutableData (10); // Create a small CFMutableDataRef + using var data = new NSMutableData (10); // Create a small CFMutableDataRef var provider = CGRenderingBufferProvider.Create (data); - Assert.That (provider, Is.Null.Or.InstanceOf (), "Should return null or a valid instance"); + Assert.That (provider, Is.Null, "This shouldn't work"); // doesn't work because I have no idea what to put in the NSData to make it valid } [Test] @@ -28,36 +26,38 @@ public void SizeProperty_DoesNotThrow () { TestRuntime.AssertXcodeVersion (26, 0); - var data = new NSMutableData (10); - var provider = CGRenderingBufferProvider.Create (data); - if (provider is not null) { - Assert.DoesNotThrow (() => { var size = provider.Size; }); - } - } - - [Test] - public void LockUnlockBytePointer_DoesNotThrow () - { - TestRuntime.AssertXcodeVersion (26, 0); - - var data = new NSMutableData (10); - var provider = CGRenderingBufferProvider.Create (data); - if (provider is not null) { - Assert.DoesNotThrow (() => { - var ptr = provider.LockBytePointer (); - provider.UnlockBytePointer (); + var size = 512; + var calledOnLockPointer = false; + var calledOnUnlockPointer = false; + var calledOnReleaseInfo = false; + var provider = CGRenderingBufferProvider.Create ((nint) 0xdeadf00d, size, + lockPointer: (info) => { + calledOnLockPointer = true; + var rv = Marshal.AllocHGlobal (renderingBufferProviderSize); + // Console.WriteLine ($"CreateAdaptive () OnLockPointer#4 ({info}) => {rv}"); + return rv; + }, + unlockPointer: (info, pointer) => { + // Console.WriteLine ($"CreateAdaptive () OnUnlockPointer#4 ({info}, {pointer})"); + calledOnUnlockPointer = true; + Marshal.FreeHGlobal (pointer); + }, + releaseInfo: (info) => { + // Console.WriteLine ($"CreateAdaptive () OnReleaseInfo#4 ({info})"); + calledOnReleaseInfo = true; }); - } + Assert.That (provider, Is.Not.Null, "provider"); + Assert.That (provider.Size, Is.EqualTo (size), "size"); } [Test] - public void GetTypeId_ReturnsTypeId () + public void GetTypeId () { TestRuntime.AssertXcodeVersion (26, 0); Assert.DoesNotThrow (() => { var typeId = CGRenderingBufferProvider.GetTypeId (); - Assert.GreaterOrEqual (typeId, 0); + Assert.That (typeId, Is.GreaterThan (0), "GetTypeId"); }); } } diff --git a/tests/monotouch-test/CoreGraphics/ShadingTest.cs b/tests/monotouch-test/CoreGraphics/ShadingTest.cs index e0edd9227b03..44220f4819c5 100644 --- a/tests/monotouch-test/CoreGraphics/ShadingTest.cs +++ b/tests/monotouch-test/CoreGraphics/ShadingTest.cs @@ -1,11 +1,5 @@ -// -// Unit tests for CGPath -// -// Authors: -// Sebastien Pouliot -// -// Copyright 2013-2014 Xamarin Inc. All rights reserved. -// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. using System; using System.IO; @@ -34,8 +28,6 @@ public void CreateAxialWithContentHeadroom () return CGShading.CreateAxial (0.5f, hdrCapableColorspace, start, end, function, true, false); }); - - TestRuntime.AssertXcodeVersion (26, 0); } [Test] From 80f4e3a16c218d22ff1693ee735d6973a893f04b Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 26 Aug 2025 15:30:54 +0200 Subject: [PATCH 5/7] Fix build --- .../CoreGraphics/CGRenderingBufferProviderTest.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs index 7fc07c0604bb..74304b8f4a91 100644 --- a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs @@ -2,6 +2,8 @@ // Licensed under the MIT License. using System; +using System.Runtime.InteropServices; + using Foundation; using CoreGraphics; using NUnit.Framework; @@ -30,7 +32,7 @@ public void SizeProperty_DoesNotThrow () var calledOnLockPointer = false; var calledOnUnlockPointer = false; var calledOnReleaseInfo = false; - var provider = CGRenderingBufferProvider.Create ((nint) 0xdeadf00d, size, + var provider = CGRenderingBufferProvider.Create ((nint) 0x0ee1f00d, size, lockPointer: (info) => { calledOnLockPointer = true; var rv = Marshal.AllocHGlobal (renderingBufferProviderSize); From 75ff93c825735b7337b16437d418fa06e47edbbc Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 26 Aug 2025 16:12:35 +0200 Subject: [PATCH 6/7] Fix --- .../CoreGraphics/CGRenderingBufferProviderTest.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs index 74304b8f4a91..f09328ab1ebd 100644 --- a/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGRenderingBufferProviderTest.cs @@ -32,10 +32,10 @@ public void SizeProperty_DoesNotThrow () var calledOnLockPointer = false; var calledOnUnlockPointer = false; var calledOnReleaseInfo = false; - var provider = CGRenderingBufferProvider.Create ((nint) 0x0ee1f00d, size, + var provider = CGRenderingBufferProvider.Create ((nint) 0x0ee1f00d, (nuint) size, lockPointer: (info) => { calledOnLockPointer = true; - var rv = Marshal.AllocHGlobal (renderingBufferProviderSize); + var rv = Marshal.AllocHGlobal (size); // Console.WriteLine ($"CreateAdaptive () OnLockPointer#4 ({info}) => {rv}"); return rv; }, @@ -49,7 +49,10 @@ public void SizeProperty_DoesNotThrow () calledOnReleaseInfo = true; }); Assert.That (provider, Is.Not.Null, "provider"); - Assert.That (provider.Size, Is.EqualTo (size), "size"); + Assert.That (provider.Size, Is.EqualTo ((nuint) size), "size"); + Assert.That (calledOnLockPointer, Is.EqualTo (false), "calledOnLockPointer"); + Assert.That (calledOnUnlockPointer, Is.EqualTo (false), "calledOnUnlockPointer"); + Assert.That (calledOnReleaseInfo, Is.EqualTo (false), "calledOnReleaseInfo"); } [Test] @@ -59,7 +62,7 @@ public void GetTypeId () Assert.DoesNotThrow (() => { var typeId = CGRenderingBufferProvider.GetTypeId (); - Assert.That (typeId, Is.GreaterThan (0), "GetTypeId"); + Assert.That (typeId, Is.GreaterThan ((nint) 0), "GetTypeId"); }); } } From f37443b3b783d9bc0071ea2b244d4a6a6b062170 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 4 Sep 2025 07:39:10 +0200 Subject: [PATCH 7/7] Fix tests. --- .../CoreGraphics/CGContentToneMappingInfoTest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/monotouch-test/CoreGraphics/CGContentToneMappingInfoTest.cs b/tests/monotouch-test/CoreGraphics/CGContentToneMappingInfoTest.cs index 9129674c8a11..c98155dea2b0 100644 --- a/tests/monotouch-test/CoreGraphics/CGContentToneMappingInfoTest.cs +++ b/tests/monotouch-test/CoreGraphics/CGContentToneMappingInfoTest.cs @@ -14,6 +14,8 @@ public class CGContentToneMappingInfoTest { [Test] public void DefaultValuesTest () { + TestRuntime.AssertXcodeVersion (16, 0); + var t = new CGContentToneMappingInfo (); Assert.AreEqual (CGToneMapping.Default, t.Method, "Method"); Assert.IsNull (t.Options, "Options"); @@ -23,6 +25,8 @@ public void DefaultValuesTest () [Test] public void PropertySetGetTest () { + TestRuntime.AssertXcodeVersion (16, 0); + var t = new CGContentToneMappingInfo (); t.Method = CGToneMapping.ImageSpecificLumaScaling; Assert.AreEqual (CGToneMapping.ImageSpecificLumaScaling, t.Method, "Method#1");