using CPF.Mac.ObjCRuntime; using System; using System.Reflection; using System.Runtime.InteropServices; namespace CPF.Mac.CoreText { [Since(3, 2)] public class CTRunDelegateOperations : IDisposable { internal GCHandle handle; protected CTRunDelegateOperations() { handle = GCHandle.Alloc(this); } public virtual void Dispose() { } public virtual float GetAscent() { return 0f; } public virtual float GetDescent() { return 0f; } public virtual float GetWidth() { return 0f; } internal CTRunDelegateCallbacks GetCallbacks() { CTRunDelegateCallbacks cTRunDelegateCallbacks = new CTRunDelegateCallbacks { version = CTRunDelegateVersion.Version1, dealloc = Deallocate }; BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; MethodInfo method; if ((method = GetType().GetMethod("GetAscent", bindingAttr)) != null && method.DeclaringType != typeof(CTRunDelegateOperations)) { cTRunDelegateCallbacks.getAscent = GetAscent; } if ((method = GetType().GetMethod("GetDescent", bindingAttr)) != null && method.DeclaringType != typeof(CTRunDelegateOperations)) { cTRunDelegateCallbacks.getDescent = GetDescent; } if ((method = GetType().GetMethod("GetWidth", bindingAttr)) != null && method.DeclaringType != typeof(CTRunDelegateOperations)) { cTRunDelegateCallbacks.getWidth = GetWidth; } return cTRunDelegateCallbacks; } [MonoPInvokeCallback(typeof(CTRunDelegateDeallocateCallback))] private static void Deallocate(IntPtr refCon) { CTRunDelegateOperations operations = GetOperations(refCon); if (operations != null) { operations.Dispose(); if (operations.handle.IsAllocated) { operations.handle.Free(); } operations.handle = default(GCHandle); } } internal static CTRunDelegateOperations GetOperations(IntPtr refCon) { return GCHandle.FromIntPtr(refCon).Target as CTRunDelegateOperations; } [MonoPInvokeCallback(typeof(CTRunDelegateGetAscentCallback))] private static float GetAscent(IntPtr refCon) { return GetOperations(refCon)?.GetAscent() ?? 0f; } [MonoPInvokeCallback(typeof(CTRunDelegateGetDescentCallback))] private static float GetDescent(IntPtr refCon) { return GetOperations(refCon)?.GetDescent() ?? 0f; } [MonoPInvokeCallback(typeof(CTRunDelegateGetWidthCallback))] private static float GetWidth(IntPtr refCon) { return GetOperations(refCon)?.GetWidth() ?? 0f; } } }