mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-04-05 17:37:51 +08:00
107 lines
3.0 KiB
C#
107 lines
3.0 KiB
C#
using CPF.Mac.Foundation;
|
|
using CPF.Mac.ObjCRuntime;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace CPF.Mac.CoreGraphics
|
|
{
|
|
public class CGFunction : INativeObject, IDisposable
|
|
{
|
|
private unsafe delegate void CGFunctionEvaluateCallback(IntPtr info, double* data, double* outData);
|
|
|
|
private struct CGFunctionCallbacks
|
|
{
|
|
public uint version;
|
|
|
|
public CGFunctionEvaluateCallback evaluate;
|
|
|
|
public IntPtr release;
|
|
}
|
|
|
|
public unsafe delegate void CGFunctionEvaluate(double* data, double* outData);
|
|
|
|
internal IntPtr handle;
|
|
|
|
private GCHandle gch;
|
|
|
|
private CGFunctionEvaluate evaluate;
|
|
|
|
public IntPtr Handle => handle;
|
|
|
|
internal CGFunction(IntPtr handle)
|
|
: this(handle, owns: false)
|
|
{
|
|
this.handle = handle;
|
|
}
|
|
|
|
[Preserve(Conditional = true)]
|
|
internal CGFunction(IntPtr handle, bool owns)
|
|
{
|
|
this.handle = handle;
|
|
if (!owns)
|
|
{
|
|
CGFunctionRetain(handle);
|
|
}
|
|
}
|
|
|
|
~CGFunction()
|
|
{
|
|
Dispose(disposing: false);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(disposing: true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
[DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")]
|
|
private static extern void CGFunctionRelease(IntPtr handle);
|
|
|
|
[DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")]
|
|
private static extern void CGFunctionRetain(IntPtr handle);
|
|
|
|
protected unsafe virtual void Dispose(bool disposing)
|
|
{
|
|
if (handle != IntPtr.Zero)
|
|
{
|
|
CGFunctionRelease(handle);
|
|
handle = IntPtr.Zero;
|
|
gch.Free();
|
|
evaluate = null;
|
|
}
|
|
}
|
|
|
|
[DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")]
|
|
private static extern IntPtr CGFunctionCreate(IntPtr data, IntPtr domainCount, double[] domain, IntPtr rangeDomain, double[] range, ref CGFunctionCallbacks callbacks);
|
|
|
|
public unsafe CGFunction(double[] domain, double[] range, CGFunctionEvaluate callback)
|
|
{
|
|
if (domain != null && domain.Length % 2 != 0)
|
|
{
|
|
throw new ArgumentException("The domain array must consist of pairs of values", "domain");
|
|
}
|
|
if (range != null && range.Length % 2 != 0)
|
|
{
|
|
throw new ArgumentException("The range array must consist of pairs of values", "range");
|
|
}
|
|
if (callback == null)
|
|
{
|
|
throw new ArgumentNullException("callback");
|
|
}
|
|
evaluate = callback;
|
|
CGFunctionCallbacks callbacks = default(CGFunctionCallbacks);
|
|
callbacks.version = 0u;
|
|
callbacks.evaluate = EvaluateCallback;
|
|
callbacks.release = IntPtr.Zero;
|
|
gch = GCHandle.Alloc(this);
|
|
handle = CGFunctionCreate(GCHandle.ToIntPtr(gch), (domain != null) ? new IntPtr(domain.Length / 2) : IntPtr.Zero, domain, (range != null) ? new IntPtr(range.Length / 2) : IntPtr.Zero, range, ref callbacks);
|
|
}
|
|
|
|
private unsafe static void EvaluateCallback(IntPtr info, double* input, double* output)
|
|
{
|
|
((CGFunction)GCHandle.FromIntPtr(info).Target).evaluate(input, output);
|
|
}
|
|
}
|
|
}
|